JSONP là gì và tại sao nó được tạo ra?


2129

Tôi hiểu JSON, nhưng không phải JSONP. Tài liệu của Wikipedia về JSON là (là) kết quả tìm kiếm hàng đầu cho JSONP. Nó nói điều này:

JSONP hoặc "JSON with padding" là một phần mở rộng JSON trong đó tiền tố được chỉ định làm đối số đầu vào của chính cuộc gọi.

Huh? Gọi gì? Điều đó không có ý nghĩa gì với tôi. JSON là một định dạng dữ liệu. Không có cuộc gọi.

Các kết quả tìm kiếm thứ 2 là từ một số anh chàng tên là Remy , người viết này về JSONP:

JSONP là phương thức tiêm thẻ script, chuyển phản hồi từ máy chủ sang hàm do người dùng chỉ định.

Tôi có thể hiểu điều đó, nhưng nó vẫn không có nghĩa gì cả.


Vậy JSONP là gì? Tại sao nó được tạo ra (vấn đề gì nó giải quyết)? Và tại sao tôi lại sử dụng nó?


Phụ lục : Tôi vừa tạo một trang mới cho JSONP trên Wikipedia; bây giờ nó có một mô tả rõ ràng và kỹ lưỡng về JSONP, dựa trên câu trả lời của jvenema .


29
Đối với bản ghi, KHÔNG sử dụng JSONP nếu bạn không tin tưởng máy chủ mà bạn đang nói chuyện với 100%. Nếu nó bị xâm phạm, trang web của bạn sẽ bị xâm phạm một cách tầm thường.
ninjagecko

7
Cũng lưu ý rằng JSONP có thể bị tấn công nếu không được triển khai chính xác.
Pacerier

3
Tôi muốn công nhận cho tác giả của JSONP, người đã đưa ra triết lý đằng sau nó: kho lưu trữ của Bob Ippolito trên JSONP . Ông giới thiệu JSONP là "một phương pháp tiêu chuẩn bất khả tri công nghệ mới cho phương pháp thẻ script để tìm nạp dữ liệu giữa các miền".
khắc nghiệt

Câu trả lời:


2047

Nó thực sự không quá phức tạp ...

Giả sử bạn đang ở trên miền example.comvà bạn muốn yêu cầu tên miền example.net. Để làm như vậy, bạn cần vượt qua các ranh giới tên miền , không có trong hầu hết các trình duyệt.

Một mục bỏ qua giới hạn này là <script>thẻ. Khi bạn sử dụng thẻ tập lệnh, giới hạn tên miền sẽ bị bỏ qua, nhưng trong các trường hợp thông thường, bạn thực sự không thể làm gì với kết quả, tập lệnh sẽ được đánh giá.

Nhập JSONP. Khi bạn thực hiện yêu cầu của mình đến một máy chủ được bật JSONP, bạn sẽ chuyển một tham số đặc biệt cho máy chủ biết một chút về trang của bạn. Bằng cách đó, máy chủ có thể kết thúc tốt đẹp phản hồi của nó theo cách mà trang của bạn có thể xử lý.

Ví dụ, giả sử máy chủ mong đợi một tham số được gọi callbackđể kích hoạt các khả năng JSONP của nó. Sau đó, yêu cầu của bạn sẽ như sau:

http://www.example.net/sample.aspx?callback=mycallback

Không có JSONP, điều này có thể trả về một số đối tượng JavaScript cơ bản, như vậy:

{ foo: 'bar' }

Tuy nhiên, với JSONP, khi máy chủ nhận được tham số "gọi lại", nó sẽ kết quả khác đi một chút, trả về một cái gì đó như thế này:

mycallback({ foo: 'bar' });

Như bạn có thể thấy, bây giờ nó sẽ gọi phương thức bạn đã chỉ định. Vì vậy, trong trang của bạn, bạn xác định chức năng gọi lại:

mycallback = function(data){
  alert(data.foo);
};

Và bây giờ, khi tập lệnh được tải, nó sẽ được đánh giá và chức năng của bạn sẽ được thực thi. Voila, yêu cầu tên miền chéo!

Cũng đáng lưu ý một vấn đề lớn với JSONP: bạn mất nhiều quyền kiểm soát yêu cầu. Ví dụ, không có cách "đẹp" nào để lấy lại mã lỗi phù hợp. Kết quả là, bạn kết thúc bằng cách sử dụng bộ hẹn giờ để theo dõi yêu cầu, v.v., điều này luôn có một chút nghi ngờ. Đề xuất cho JSONRequest là một giải pháp tuyệt vời để cho phép kịch bản tên miền chéo, duy trì bảo mật và cho phép kiểm soát đúng yêu cầu.

Những ngày này (2015), CORS là cách tiếp cận được đề xuất so với JSONRequest. JSONP vẫn hữu ích cho hỗ trợ trình duyệt cũ hơn, nhưng với ý nghĩa bảo mật, trừ khi bạn không có lựa chọn nào CORS là lựa chọn tốt hơn.


180
Xin lưu ý rằng việc sử dụng JSONP có một số ý nghĩa bảo mật. Vì JSONP thực sự là javascript, nó có thể làm mọi thứ mà javascript có thể làm, vì vậy bạn cần tin tưởng vào nhà cung cấp dữ liệu JSONP. Tôi đã viết một bài đăng trên blog về nó ở đây: erlend.oftedal.no/blog/?blogid=97
Erlend

72
Có thực sự có bất kỳ hàm ý bảo mật mới nào trong JSONP không có trong thẻ <script> không? Với thẻ script, trình duyệt hoàn toàn tin tưởng vào máy chủ để cung cấp Javascript không gây hại, mà trình duyệt đánh giá một cách mù quáng. JSONP có thay đổi thực tế đó không? Có vẻ như không phải vậy.
Cheeso

23
Không, nó không. Bạn tin tưởng nó để phân phối javascript, điều tương tự áp dụng cho JSONP.
jvenema

15
Điều đáng chú ý là bạn có thể tăng cường bảo mật một chút bằng cách thay đổi cách dữ liệu được trả về. Nếu bạn trả về tập lệnh ở định dạng JSON thực như mycallback ('{"foo": "bar"}') (lưu ý rằng tham số bây giờ là một chuỗi), thì bạn có thể tự phân tích dữ liệu theo cách thủ công để "làm sạch" dữ liệu đó trước đó đánh giá.
jvenema

8
CURL là một giải pháp phía máy chủ, không phải phía máy khách. Họ phục vụ hai mục đích khác nhau.
jvenema

712

JSONP thực sự là một mẹo đơn giản để vượt qua chính sách 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ẻ HTML script , 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';

Lưu ý 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.

Ví dụ JavaScript cơ bản (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 bằ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.)


34
Cảm ơn đã giải thích thẻ script. Tôi đã không thể tìm ra cách chính sách bảo mật tên miền chéo được bỏ qua bởi JSONP. Sau lời giải thích, tôi cảm thấy thật ngu ngốc khi bỏ lỡ vấn đề ...
Eduard

13
Đây là một câu trả lời bổ sung rất tốt cho câu trả lời của jvenema - Tôi không hiểu tại sao gọi lại là cần thiết cho đến khi bạn chỉ ra rằng dữ liệu json sẽ phải được truy cập thông qua phần tử script.
Matt

5
Cảm ơn lời giải thích sáng suốt như vậy. Tôi ước sách giáo khoa đại học của tôi được viết bởi những người như bạn :)
hashbrown

1
Giải thích tốt hơn là trước đó. Tất nhiên - đoạn trích của bạn "những cái 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ạ?" cũng là mở mắt cho tôi. Mã ví dụ trong rất nhiều lừng lẫy.
SIslam

đệm không phải là nghĩa đen. nó là một phép ẩn dụ vì vậy nó có nghĩa là "JSON với một số 'khoảng trắng'". lol
marvinIsSacul

48

JSONP hoạt động bằng cách xây dựng một phần tử script script của Wikipedia (trong phần đánh dấu HTML hoặc được chèn vào DOM thông qua JavaScript), yêu cầu đến một vị trí dịch vụ dữ liệu từ xa. Phản hồi là một javascript được tải vào trình duyệt của bạn với tên của hàm được xác định trước cùng với tham số được truyền qua đó là dữ liệu JSON được yêu cầu. Khi tập lệnh thực thi, hàm được gọi cùng với dữ liệu JSON, cho phép trang yêu cầu nhận và xử lý dữ liệu.

Để đọc thêm, hãy truy cập: https://bloss.s.co./2013/07/15/secret-behind-jsonp/

đoạn mã phía máy khách

    <!DOCTYPE html>
    <html lang="en">
    <head>
     <title>AvLabz - CORS : The Secrets Behind JSONP </title>
     <meta charset="UTF-8" />
    </head>
    <body>
      <input type="text" id="username" placeholder="Enter Your Name"/>
      <button type="submit" onclick="sendRequest()"> Send Request to Server </button>
    <script>
    "use strict";
    //Construct the script tag at Runtime
    function requestServerCall(url) {
      var head = document.head;
      var script = document.createElement("script");

      script.setAttribute("src", url);
      head.appendChild(script);
      head.removeChild(script);
    }

    //Predefined callback function    
    function jsonpCallback(data) {
      alert(data.message); // Response data from the server
    }

    //Reference to the input field
    var username = document.getElementById("username");

    //Send Request to Server
    function sendRequest() {
      // Edit with your Web Service URL
      requestServerCall("http://localhost/PHP_Series/CORS/myService.php?callback=jsonpCallback&message="+username.value+"");
    }    

  </script>
   </body>
   </html>

Phần phía máy chủ của mã PHP

<?php
    header("Content-Type: application/javascript");
    $callback = $_GET["callback"];
    $message = $_GET["message"]." you got a response from server yipeee!!!";
    $jsonResponse = "{\"message\":\"" . $message . "\"}";
    echo $callback . "(" . $jsonResponse . ")";
?>

3
liên kết ở đầu chỉ 404s bây giờ
Kevin Beal


42

Bởi vì bạn có thể yêu cầu máy chủ thêm tiền tố vào đối tượng JSON được trả về. Ví dụ

function_prefix(json_object);

để trình duyệt eval"nội tuyến" chuỗi JSON dưới dạng một biểu thức. Thủ thuật này giúp máy chủ có thể "tiêm" mã javascript trực tiếp vào trình duyệt Máy khách và điều này có thể bỏ qua các hạn chế "cùng nguồn gốc".

Nói cách khác, bạn có thể đạt được trao đổi dữ liệu giữa các miền .


Thông thường, XMLHttpRequestkhông cho phép trao đổi dữ liệu giữa các miền trực tiếp (người ta cần phải đi qua một máy chủ trong cùng một tên miền) trong khi:

<script src="some_other_domain/some_data.js&prefix=function_prefix> `người ta có thể truy cập dữ liệu từ một miền khác với nguồn gốc.


Cũng đáng chú ý: mặc dù máy chủ nên được coi là "đáng tin cậy" trước khi thử loại "mánh khóe" đó, các tác dụng phụ của thay đổi có thể có trong định dạng đối tượng, v.v. Nếu một function_prefix(tức là một hàm js thích hợp) được sử dụng để nhận đối tượng JSON, thì hàm đã nói có thể thực hiện kiểm tra trước khi chấp nhận / xử lý thêm dữ liệu được trả về.


"Nối tiền tố" thật khó hiểu :)
jub0bs

19

JSONP là một cách tuyệt vời để khắc phục các lỗi kịch bản tên miền chéo. Bạn có thể sử dụng dịch vụ JSONP hoàn toàn với JS mà không phải triển khai proxy AJAX ở phía máy chủ.

Bạn có thể sử dụng dịch vụ b1t.co để xem nó hoạt động như thế nào. Đây là một dịch vụ JSONP miễn phí cho phép bạn thu nhỏ URL của mình. Đây là url để sử dụng cho dịch vụ:

http://b1t.co/Site/api/External/MakeUrlWithGet?callback=[resultsCallBack[&url=[escopedUrlToMinify]

Ví dụ: cuộc gọi, http://b1t.co/Site/api/External/MakeUrlWithGet?callback=whthingJavascriptName&url=google.com

sẽ trở lại

whateverJavascriptName({"success":true,"url":"http://google.com","shortUrl":"http://b1t.co/54"});

Và do đó, khi được tải trong js của bạn dưới dạng src, nó sẽ tự động chạy bất cứ thứ gìJavascriptName mà bạn nên triển khai như chức năng gọi lại của mình:

function minifyResultsCallBack(data)
{
    document.getElementById("results").innerHTML = JSON.stringify(data);
}

Để thực sự thực hiện cuộc gọi JSONP, bạn có thể thực hiện theo một số cách (bao gồm cả sử dụng jQuery) nhưng đây là một ví dụ thuần túy:

function minify(urlToMinify)
{
   url = escape(urlToMinify);
   var s = document.createElement('script');
   s.id = 'dynScript';
   s.type='text/javascript';
   s.src = "http://b1t.co/Site/api/External/MakeUrlWithGet?callback=resultsCallBack&url=" + url;
   document.getElementsByTagName('head')[0].appendChild(s);
}

Một ví dụ từng bước và một dịch vụ web jsonp để thực hành có sẵn tại: bài đăng này


2
Cảm ơn đã gửi câu trả lời của bạn! Xin lưu ý rằng bạn nên đăng các phần thiết yếu của câu trả lời tại đây, trên trang web này hoặc rủi ro bài đăng của bạn bị xóa Xem Câu hỏi thường gặp trong đó đề cập đến câu trả lời 'hầu như không nhiều hơn một liên kết'. Bạn vẫn có thể bao gồm liên kết nếu bạn muốn, nhưng chỉ là một 'tài liệu tham khảo'. Câu trả lời nên tự đứng mà không cần liên kết.
Taryn

14

Một ví dụ đơn giản cho việc sử dụng JSONP.

khách hàng.html

    <html>
    <head>
   </head>
     body>


    <input type="button" id="001" onclick=gO("getCompany") value="Company"  />
    <input type="button" id="002" onclick=gO("getPosition") value="Position"/>
    <h3>
    <div id="101">

    </div>
    </h3>

    <script type="text/javascript">

    var elem=document.getElementById("101");

    function gO(callback){

    script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'http://localhost/test/server.php?callback='+callback;
    elem.appendChild(script);
    elem.removeChild(script);


    }

    function getCompany(data){

    var message="The company you work for is "+data.company +"<img src='"+data.image+"'/   >";
    elem.innerHTML=message;
}

    function getPosition(data){
    var message="The position you are offered is "+data.position;
    elem.innerHTML=message;
    }
    </script>
    </body>
    </html>

máy chủ.php

  <?php

    $callback=$_GET["callback"];
    echo $callback;

    if($callback=='getCompany')
    $response="({\"company\":\"Google\",\"image\":\"xyz.jpg\"})";

    else
    $response="({\"position\":\"Development Intern\"})";
    echo $response;

    ?>    

8

Trước khi hiểu JSONP, bạn cần biết định dạng JSON và XML. Hiện tại định dạng dữ liệu được sử dụng thường xuyên nhất trên web là XML, nhưng XML rất phức tạp. Nó làm cho người dùng bất tiện khi xử lý nhúng trong các trang Web.

Để làm cho JavaScript có thể dễ dàng trao đổi dữ liệu, ngay cả khi là chương trình xử lý dữ liệu, chúng tôi sử dụng từ ngữ theo các đối tượng JavaScript và phát triển một định dạng trao đổi dữ liệu đơn giản, đó là JSON. JSON có thể được sử dụng làm dữ liệu hoặc làm chương trình JavaScript.

JSON có thể được nhúng trực tiếp vào JavaScript, bằng cách sử dụng chúng, bạn có thể thực thi trực tiếp chương trình JSON nhất định, nhưng do các ràng buộc bảo mật, cơ chế Sandbox của trình duyệt sẽ vô hiệu hóa thực thi mã JSON tên miền chéo.

Để tạo JSON có thể được thông qua sau khi thực hiện, chúng tôi đã phát triển JSONP. JSONP bỏ qua các giới hạn bảo mật của trình duyệt với chức năng Gọi lại JavaScript và thẻ <script>.

Vì vậy, trong ngắn hạn, nó giải thích JSONP là gì, vấn đề gì nó giải quyết (khi nào nên sử dụng nó).


4
Tôi đã đánh giá thấp điều này bởi vì tôi không tin rằng tuyên bố rằng XML là định dạng dữ liệu được sử dụng nhiều nhất trên web vào tháng 12/2015.
RobbyD

Nó vẫn không hiểu tại sao jsonp được sử dụng thay vì json. Tất cả những hạn chế bảo mật đến từ đâu? Tại sao chúng ta có thể sử dụng jsonp nhưng không phải json cho các tên miền chéo?
Merunas Grincala viêm

6

TL; DR

JSONP là một thủ thuật cũ được phát minh để vượt qua giới hạn bảo mật cấm chúng tôi lấy dữ liệu JSON từ một máy chủ khác ( nguồn gốc khác * ).

Thủ thuật này hoạt động bằng cách sử dụng <script>thẻ yêu cầu JSON từ nơi đó, ví dụ : { "user":"Smith" }, nhưng được bao bọc trong một hàm, JSONP thực tế ("JSON với Padding"):

peopleDataJSONP({"user":"Smith"})

Nhận nó dưới dạng này cho phép chúng tôi sử dụng dữ liệu trong peopleDataJSONPchức năng của mình. JSONP là một thực tiễn xấu , không sử dụng nó (đọc bên dưới)


Vấn đề

Giả sử chúng tôi đang điều hướng ourweb.comvà chúng tôi muốn lấy dữ liệu JSON (hoặc bất kỳ dữ liệu thô nào thực sự) từ đó anotherweb.com. Nếu chúng tôi sử dụng yêu cầu GET (như XMLHttpRequest, một fetchcuộc gọi $.ajax, v.v.), trình duyệt của chúng tôi sẽ cho chúng tôi biết rằng nó không được phép với lỗi xấu này:

Lỗi bảng điều khiển Chrome CORS

Làm thế nào để có được dữ liệu chúng ta muốn? Chà, <script>các thẻ không bị hạn chế toàn bộ máy chủ (nguồn gốc *) này! Đó là lý do tại sao chúng tôi có thể tải thư viện như jQuery hoặc Google Maps từ bất kỳ máy chủ nào, chẳng hạn như CDN, mà không có bất kỳ lỗi nào.

Điểm quan trọng : nếu bạn nghĩ về nó, các thư viện đó là mã JS thực tế, có thể chạy được (thường là một hàm lớn với tất cả logic bên trong). Nhưng dữ liệu thô? Dữ liệu JSON không phải là mã . Không có gì để chạy; nó chỉ là dữ liệu đơn giản.

Do đó, không có cách nào để xử lý hoặc thao túng dữ liệu quý giá của chúng tôi. Trình duyệt sẽ tải xuống dữ liệu được chỉ ra bởi <script>thẻ của chúng tôi và khi xử lý, nó sẽ khiếu nại đúng:

wtf này là {"user":"Smith"}crap chúng tôi tải? Đó không phải là mã. Tôi không thể tính toán, lỗi cú pháp!


Bản hack JSONP

Cách cũ / hacky để sử dụng dữ liệu đó? Chúng tôi cần máy chủ đó gửi nó với một số logic, vì vậy khi được tải, mã của bạn trong trình duyệt sẽ có thể sử dụng dữ liệu nói trên. Vì vậy, máy chủ nước ngoài gửi cho chúng tôi dữ liệu JSON bên trong hàm JS. Dữ liệu được thiết lập làm đầu vào của chức năng đó. Nó trông như thế này:

peopleDataJSONP({"user":"Smith"})

mà làm cho nó mã JS trình duyệt của chúng tôi sẽ phân tích mà không phàn nàn! Chính xác như nó làm với thư viện jQuery. Bây giờ, để có được nó như thế, máy khách "yêu cầu" máy chủ thân thiện với JSONP cho nó, thường được thực hiện như thế này:

<script src="https://anotherweb.com/api/data-from-people.json?myCallback=peopleDataJSONP"></script>

Trình duyệt của chúng tôi sẽ nhận được JSONP với tên hàm đó, do đó chúng tôi cần một hàm có cùng tên trong mã của chúng tôi, như sau:

const peopleDataJSONP = function(data){
  alert(data.user); // "Smith"
}

Hoặc như thế này, kết quả tương tự:

function peopleDataJSONP(data){
  alert(data.user); // "Smith"
}

Trình duyệt sẽ tải xuống JSONP và chạy nó, gọi hàm của chúng ta , trong đó đối số datasẽ là JSON của chúng ta. Bây giờ chúng tôi có thể làm với dữ liệu của mình bất cứ điều gì chúng tôi muốn.


Không sử dụng JSONP, sử dụng CORS

JSONP là một hack nhiều trang web với một vài nhược điểm:

  • Chúng tôi chỉ có thể thực hiện các yêu cầu NHẬN
  • Vì đó là một yêu cầu GET được kích hoạt bởi một thẻ script đơn giản, chúng tôi không nhận được các lỗi hữu ích hoặc thông tin tiến trình
  • Ngoài ra còn có một số lo ngại về bảo mật, như chạy trong mã JS khách hàng của bạn có thể bị thay đổi thành tải trọng độc hại
  • Nó chỉ giải quyết vấn đề với dữ liệu JSON, nhưng chính sách bảo mật cùng nguồn gốc áp dụng cho các dữ liệu khác (WebFonts, hình ảnh / video được vẽ bằng drawImage () ...)
  • Nó không phải là rất thanh lịch cũng không thể đọc được.

Điều đáng nói là ngày nay không cần sử dụng nó .

JSONP là mẹo để lấy dữ liệu JSON từ một máy chủ khác, nhưng chúng tôi sẽ vi phạm nguyên tắc bảo mật tương tự (Cùng nguồn gốc) nếu chúng tôi cần các loại công cụ chéo trang khác.

Bạn nên đọc về CORS ở đây , nhưng ý chính của nó là:

Chia sẻ tài nguyên nguồn gốc chéo (CORS) là một cơ chế sử dụng các tiêu đề HTTP bổ sung để báo cho các trình duyệt cung cấp cho ứng dụng web chạy ở một nguồn gốc, truy cập vào các tài nguyên được chọn từ một nguồn gốc khác. Một ứng dụng web thực hiện một yêu cầu HTTP có nguồn gốc chéo khi nó yêu cầu một tài nguyên có nguồn gốc khác (miền, giao thức hoặc cổng) từ chính nó.



* nguồn gốc được xác định bởi 3 điều: giao thức , cổngmáy chủ . Vì vậy, ví dụ, https://web.comlà một nguồn gốc khác với http://web.com(giao thức khác nhau) và https://web.com:8081(cổng khác nhau) và rõ ràng https://thatotherweb.net(máy chủ khác nhau)


1
Này anh bạn, điều này cung cấp sự rõ ràng 100% như một chú thích cho câu trả lời được phê duyệt! Cảm ơn vì điều này ....
M'Baku

4

Các câu trả lời tuyệt vời đã được đưa ra, tôi chỉ cần đưa ra phần của mình dưới dạng các khối mã trong javascript (Tôi cũng sẽ bao gồm giải pháp hiện đại hơn và tốt hơn cho các yêu cầu xuất xứ chéo: CORS với HTTP Headers):

JSONP:

1.client_jsonp.js

$.ajax({
    url: "http://api_test_server.proudlygeek.c9.io/?callback=?",
    dataType: "jsonp",
    success: function(data) {
        console.log(data);    
    }
});​​​​​​​​​​​​​​​​​​

2.server_jsonp.js

var http = require("http"),
    url  = require("url");

var server = http.createServer(function(req, res) {

    var callback = url.parse(req.url, true).query.callback || "myCallback";
    console.log(url.parse(req.url, true).query.callback);

    var data = {
        'name': "Gianpiero",
        'last': "Fiorelli",
        'age': 37
    };

    data = callback + '(' + JSON.stringify(data) + ');';

    res.writeHead(200, {'Content-Type': 'application/json'});
    res.end(data);
});

server.listen(process.env.PORT, process.env.IP);

console.log('Server running at '  + process.env.PORT + ':' + process.env.IP);

CORS :

3.client_cors.js

$.ajax({
    url: "http://api_test_server.proudlygeek.c9.io/",
    success: function(data) {
        console.log(data);    
    }
});​

4.server_cors.js

var http = require("http"),
    url  = require("url");

var server = http.createServer(function(req, res) {
    console.log(req.headers);

    var data = {
        'name': "Gianpiero",
        'last': "Fiorelli",
        'age': 37
    };

    res.writeHead(200, {
        'Content-Type': 'application/json',
        'Access-Control-Allow-Origin': '*'
    });

    res.end(JSON.stringify(data));
});

server.listen(process.env.PORT, process.env.IP);

console.log('Server running at '  + process.env.PORT + ':' + process.env.IP);

1

JSONP là viết tắt của JSON với Padding .

Đây là trang web, với các ví dụ tuyệt vời , với lời giải thích từ việc sử dụng đơn giản nhất kỹ thuật này đến JavaScript tiên tiến nhất trong mặt phẳng:

w3schools.com / JSONP

Một trong những kỹ thuật yêu thích của tôi được mô tả ở trên là Kết quả JSON động , cho phép gửi JSON đến tệp PHP trong tham số URL và để tệp PHP cũng trả về một đối tượng JSON dựa trên thông tin mà nó nhận được .

Các công cụ như jQuery cũng có các phương tiện để sử dụng JSONP :

jQuery.ajax({
  url: "https://data.acgov.org/resource/k9se-aps6.json?city=Berkeley",
  jsonp: "callbackName",
  dataType: "jsonp"
}).done(
  response => console.log(response)
);
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.