Ví dụ cơ bản về việc sử dụng .ajax () với JSONP?


185

Xin ai đó có thể giúp tôi tìm ra cách bắt đầu với JSONP không?

Mã số:

$('document').ready(function() {
    var pm_url = 'http://twitter.com/status';
    pm_url += '/user_timeline/stephenfry.json';
    pm_url += '?count=10&callback=photos';
    var photos = function (data) {
     alert(data);
    };
    $.ajax({
        url: pm_url,
        dataType: 'jsonp',
        jsonpCallback: 'photos',
        jsonp: false,
    });
});

Fiddle: http://jsfiddle.net/R7EPt/6/

Nên tạo một cảnh báo, theo như tôi có thể tìm ra từ tài liệu: không (nhưng cũng không tạo ra bất kỳ lỗi nào).

cảm ơn.


$ .ajax ({url: pm_url, dataType: 'jsonp', jsonpCallback: photos, jsonp: false,}); Bạn đã nhập ảnh dưới dạng một chuỗi.
wOlVeRiNe

Câu trả lời:


388

JSONP thực sự là một mẹo đơn giản để vượt qua chính sách tên miền tương tự XMLHttpRequest . (Như bạn biết, người ta không thể gửi yêu cầu AJAX (XMLHttpRequest) đến một tên miền khác.)

Vì vậy - thay vì sử dụng XMLHttpRequest, chúng ta phải sử dụng các thẻ HTMLl tập lệnh , những thẻ bạn thường sử dụng để tải các tệp JS, để JS lấy dữ liệu từ một tên miền khác. Nghe có vẻ lạ?

Điều đó là - hóa ra các thẻ script có thể được sử dụng theo cách tương tự như XMLHttpRequest ! Kiểm tra này:

script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://www.someWebApiServer.com/some-data";

Bạn sẽ kết thúc với một đoạn script trông như thế này sau khi nó tải dữ liệu:

<script>
{['some string 1', 'some data', 'whatever data']}
</script>

Tuy nhiên điều này hơi bất tiện, vì chúng tôi phải tìm nạp mảng này từ thẻ script . Vì vậy, những người tạo JSONP đã quyết định rằng nó sẽ hoạt động tốt hơn (và nó là):

script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://www.someWebApiServer.com/some-data?callback=my_callback";

Chú ý chức năng my_callback đằng kia? Vì vậy - khi máy chủ JSONP nhận được yêu cầu của bạn và tìm thấy tham số gọi lại - thay vì trả về mảng JS đơn giản, nó sẽ trả về điều này:

my_callback({['some string 1', 'some data', 'whatever data']});

Xem lợi nhuận ở đâu: bây giờ chúng tôi nhận được cuộc gọi lại tự động ( my_callback ) sẽ được kích hoạt sau khi chúng tôi nhận được dữ liệu. Đó là tất cả những gì cần biết về JSONP : đó là thẻ gọi lại và thẻ script.


LƯU Ý:
Đây là những ví dụ đơn giản về việc sử dụng JSONP, đây không phải là các tập lệnh sẵn sàng sản xuất.

Trình diễn RAW JavaScript (nguồn cấp dữ liệu Twitter đơn giản bằng JSONP):

<html>
    <head>
    </head>
    <body>
        <div id = 'twitterFeed'></div>
        <script>
        function myCallback(dataWeGotViaJsonp){
            var text = '';
            var len = dataWeGotViaJsonp.length;
            for(var i=0;i<len;i++){
                twitterEntry = dataWeGotViaJsonp[i];
                text += '<p><img src = "' + twitterEntry.user.profile_image_url_https +'"/>' + twitterEntry['text'] + '</p>'
            }
            document.getElementById('twitterFeed').innerHTML = text;
        }
        </script>
        <script type="text/javascript" src="http://twitter.com/status/user_timeline/padraicb.json?count=10&callback=myCallback"></script>
    </body>
</html>


Ví dụ jQuery cơ bản (nguồn cấp dữ liệu Twitter đơn giản sử dụng JSONP):

<html>
    <head>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
        <script>
            $(document).ready(function(){
                $.ajax({
                    url: 'http://twitter.com/status/user_timeline/padraicb.json?count=10',
                    dataType: 'jsonp',
                    success: function(dataWeGotViaJsonp){
                        var text = '';
                        var len = dataWeGotViaJsonp.length;
                        for(var i=0;i<len;i++){
                            twitterEntry = dataWeGotViaJsonp[i];
                            text += '<p><img src = "' + twitterEntry.user.profile_image_url_https +'"/>' + twitterEntry['text'] + '</p>'
                        }
                        $('#twitterFeed').html(text);
                    }
                });
            })
        </script>
    </head>
    <body>
        <div id = 'twitterFeed'></div>
    </body>
</html>


JSONP là viết tắt của JSON với Padding . (kỹ thuật được đặt tên rất kém vì nó thực sự không liên quan gì đến những gì hầu hết mọi người sẽ nghĩ về cái tên pad padding.)


3
Câu trả lời này hiện đã lỗi thời vì các trình duyệt hiện hỗ trợ Access-Control-Allow-Origincác tiêu đề cho phép thực hiện các cuộc gọi Ajax thông thường cho một số miền có nguồn gốc chéo.
jfriend00

Hãy nhớ rằng bạn không thể thực hiện POST mẫu với JSONP. Thêm thông tin tại đây: markhneedham.com/blog/2009/08/27/ từ
thdoan

4
Bạn phải cân nhắc điều gì nếu bạn muốn làm cho các kịch bản này sẵn sàng sản xuất?
khách

1
Wow, điều này thực sự hữu ích! Cuối cùng tôi cũng biết chính xác JSONP là gì và nó hoạt động như thế nào!
Jerry Liu

145

Thậm chí còn có cách dễ dàng hơn để làm việc với JSONP bằng jQuery

$.getJSON("http://example.com/something.json?callback=?", function(result){
   //response data are now in the result variable
   alert(result);
});

Phần ?cuối của URL cho jQuery biết rằng đó là một yêu cầu JSONP thay vì JSON. Thanh ghi jQuery và gọi hàm gọi lại tự động.

Để biết thêm chi tiết, tham khảo tài liệu jQuery.getJSON .


2
@PetrPeller, Có vẻ tuyệt vời nhưng tôi dường như không tạo ra một sản phẩm từ nó. Bạn có thể một lần nhìn thấy điều này? JSFiddle Nó cảnh báo không có dữ liệu. Có lẽ tôi đã bỏ lỡ điều gì đó
tika 18/07/14

@xDNP Phản hồi JSONP phải được máy chủ hỗ trợ. Máy chủ của bạn dường như không hỗ trợ nó vì tôi không thể thấy bất kỳ cuộc gọi lại nào được thêm vào đây: mylivecanvas.com/api/ mẹo . Ngoài ra, bạn nên sử dụng &callback=?vì nó không phải là tham số đầu tiên trong trường hợp của bạn.
Petr Peller

1
@PetrPeller Tôi rất quan tâm đến giải pháp của bạn. Nhưng, điều đó không làm việc với tôi. Tôi không muốn đăng một câu hỏi mới nhưng nó không giúp tôi. Những gì hiện dường như không hỗ trợ bởi máy chủ trung bình? Tôi nên làm gì? Và bạn có thể cho tôi một URL hoàn chỉnh hoạt động cho máy chủ của tôi không? Tôi sẽ biết ơn bạn. Tôi có cần cấu hình máy chủ nào không?
tika

3
Chỉnh sửa cuối cùng là gì, "Làm ơn đừng sử dụng jQuery nữa!" nghĩa là?
ParkCheolu

1
Bây giờ là năm 2018 và tôi không chắc những gì được cho là sẽ được sử dụng trong năm 2017!
Hội trường Vasily

28

Để đáp ứng với OP, có hai vấn đề với mã của bạn: bạn cần đặt jsonp = 'gọi lại' và thêm chức năng gọi lại trong một biến như bạn dường như không hoạt động.

Cập nhật: khi tôi viết bài này, API Twitter chỉ mở, nhưng họ đã thay đổi và bây giờ yêu cầu xác thực. Tôi đã thay đổi ví dụ thứ hai thành một ví dụ hoạt động (2014Q1), nhưng bây giờ sử dụng github.

Điều này không còn hoạt động nữa - như một bài tập, hãy xem bạn có thể thay thế nó bằng API Github không:

$('document').ready(function() {
    var pm_url = 'http://twitter.com/status';
    pm_url += '/user_timeline/stephenfry.json';
    pm_url += '?count=10&callback=photos';
    $.ajax({
        url: pm_url,
        dataType: 'jsonp',
        jsonpCallback: 'photos',
        jsonp: 'callback',
    });
});
function photos (data) {
    alert(data);
    console.log(data);
};

mặc dù cảnh báo () trong một mảng như thế không thực sự hoạt động tốt ... Tab "Net" trong Fireorms sẽ hiển thị cho bạn JSON đúng cách. Một mẹo hữu ích khác là làm

alert(JSON.stringify(data));

Bạn cũng có thể sử dụng phương thức jQuery.getJSON . Đây là một ví dụ html hoàn chỉnh có được danh sách "ý chính" từ github. Bằng cách này, nó tạo ra một hàm gọi lại được đặt tên ngẫu nhiên cho bạn, đó là "gọi lại =?" Cuối cùng trong url.

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>JQuery (cross-domain) JSONP Twitter example</title>
        <script type="text/javascript"src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
        <script>
            $(document).ready(function(){
                $.getJSON('https://api.github.com/gists?callback=?', function(response){
                    $.each(response.data, function(i, gist){
                        $('#gists').append('<li>' + gist.user.login + " (<a href='" + gist.html_url + "'>" + 
                            (gist.description == "" ? "undescribed" : gist.description) + '</a>)</li>');
                    });
                });
            });
        </script>
    </head>
    <body>
        <ul id="gists"></ul>
    </body>
</html>

2
Bạn nói đúng, nó không hoạt động nữa. Twitter đã thay đổi API của họ.
PapaFreud

3
<!DOCTYPE html>
<html>
<head>
<style>img{ height: 100px; float: left; }</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<title>An JSONP example </title>
</head>
<body>
<!-- DIV FOR SHOWING IMAGES -->
<div id="images">
</div>
<!-- SCRIPT FOR GETTING IMAGES FROM FLICKER.COM USING JSONP -->
<script>
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",
{
  format: "json"
},
//RETURNED RESPONSE DATA IS LOOPED AND ONLY IMAGE IS APPENDED TO IMAGE DIV
function(data) {
  $.each(data.items, function(i,item){
  $("<img/>").attr("src", item.media.m).appendTo("#images");

 });
});</script>
</body>
</html> 

Đoạn mã trên giúp lấy hình ảnh từ API Flicker. Điều này sử dụng phương thức GET để lấy hình ảnh bằng JSONP. Nó có thể được tìm thấy chi tiết ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.