首頁 > web前端 > js教程 > JQuery的JSONP用示例解釋了

JQuery的JSONP用示例解釋了

William Shakespeare
發布: 2025-02-17 10:34:10
原創
165 人瀏覽過

jQuery's JSONP Explained with Examples

要點總結

  • JSONP(帶填充的 JSON)允許跨域 Ajax 調用,從而規避了限制腳本訪問不同來源數據的同源策略。這是通過讓服務器返回包含函數調用的 JSON 數據來實現的,瀏覽器可以解釋該函數調用。
  • 雖然 JSONP 對於從不同來源獲取數據和訪問各種服務的內容很有價值,但它也有一些局限性。 JSONP 只能執行跨域 GET 請求,並且必須由服務器顯式支持。它還存在潛在的安全問題,因為它為跨站點腳本 (XSS) 攻擊打開了可能性。
  • 同源策略的其他解決方案包括使用代理或實現跨源資源共享 (CORS)。代理允許服務器端代碼執行跨源請求,而 CORS 通過在響應中包含新的 Access-Control-Allow-Origin HTTP 標頭來允許瀏覽器進行跨域通信。但是,每種方法都有其自身的缺點和局限性。

這篇文章於 2016 年 6 月 23 日進行了更新,以解決質量問題。舊文章的相關評論已被刪除。如果您正在開發基於Web 的應用程序,並且嘗試從不受您控制的域加載數據,則您很可能在瀏覽器的控制台中看到以下消息:XMLHttpRequest cannot load https://www.php .cn/link/0df0dbfc4725c2259dc0bb045e9bf6d2. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://www.php.cn/link/28db3b5e7bfadf38b792da7192530ac1' is therefore not allowed access.

在本文中,我們將探討導致此錯誤的原因,以及如何通過使用 jQuery 和 JSONP 來進行跨域 Ajax 調用來解決此問題。

同源策略

常規網頁可以使用 XMLHttpRequest 對象向遠程服務器發送和接收數據,但是同源策略限制了它們可以執行的操作。這是瀏覽器安全模型中的一個重要概念,它規定網頁瀏覽器可能只允許頁面 A 上的腳本訪問頁面 B 上的數據,如果這兩個頁面具有相同的來源。頁面的來源由其協議主機端口號定義。例如,此頁面的來源是“https”、“www.sitepoint.com”、“80”。同源策略是一種安全機制。它可以防止腳本從您的域讀取數據並將其發送到它們的服務器。如果沒有這個,惡意網站很容易將您的會話信息抓取到另一個站點(例如 Gmail 或 Twitter),並代表您執行操作。不幸的是,它還會導致我們上面看到的錯誤,並且經常會給試圖完成合法任務的開發人員帶來麻煩。

失敗的示例

讓我們看看什麼不起作用。這是一個位於不同域上的 JSON 文件,我們希望使用 jQuery 的 getJSON 方法加載它。

$.getJSON(
  "http://run.plnkr.co/plunks/v8xyYN64V4nqCshgjKms/data-1.json",
  function(json) { console.log(json); }
);
登入後複製
登入後複製

如果您在瀏覽器中打開控制台嘗試一下,您將看到類似於上面提到的消息。那麼我們能做什麼呢?

可能的解決方法

幸運的是,並非所有內容都受同源策略的影響。例如,完全可以將圖像或腳本從不同域加載到您的頁面中——當您從 CDN 包含 jQuery(例如)時,您正在執行此操作。這意味著我們可以創建一個 <script> 標籤,將其 src 屬性設置為我們的 JSON 文件,並將其註入頁面。

var script = $("<script>", {
    src: "http://run.plnkr.co/plunks/v8xyYN64V4nqCshgjKms/data-1.json",
    type: "application/json"
  }
);

$("head").append(script);
登入後複製

雖然這有效,但對我們幫助不大,因為我們無法訪問它包含的數據。

JSONP 入門

JSONP(代錶帶填充的 JSON)基於此技術,並為我們提供了一種訪問返回數據的方法。它是通過讓服務器返回包含函數調用(“填充”)的 JSON 數據來實現的,然後瀏覽器可以解釋該函數調用。此函數必須在評估 JSONP 響應的頁面中定義。

讓我們看看之前的示例是什麼樣的。這是一個更新的 JSON 文件,它將原始 JSON 數據包裝在一個 jsonCallback 函數中。

function jsonCallback(json){
  console.log(json);
}

$.ajax({
  url: "http://run.plnkr.co/plunks/v8xyYN64V4nqCshgjKms/data-2.json",
  dataType: "jsonp"
});
登入後複製

這會將預期結果記錄到控制台中。我們現在有了(儘管相當有限)跨域 Ajax。

第三方 API

一些第三方 API 允許您指定回調函數的名稱,當請求返回時應執行該函數。一個這樣的 API 是 GitHub API。

在下面的示例中,我們獲取 John Resig(jQuery 創建者)的用戶信息,並使用 logResults 回調函數將響應記錄到控制台中。

function logResults(json){
  console.log(json);
}

$.ajax({
  url: "https://api.github.com/users/jeresig",
  dataType: "jsonp",
  jsonpCallback: "logResults"
});
登入後複製

這也可以寫成:

$.getJSON("https://api.github.com/users/jeresig?callback=?",function(json){
  console.log(json);
});
登入後複製

URL 末尾的 ? 告訴 jQuery 它正在處理 JSONP 請求而不是 JSON。然後,jQuery 自動註冊回調函數,當請求返回時它會調用該函數。

如果您想了解更多關於 jQuery 的 getJSON 方法的信息,請查看:Ajax/jQuery.getJSON 簡單示例

注意事項

但正如您現在可能已經意識到的那樣,這種方法有一些缺點。

例如,JSONP 只能執行跨域 GET 請求,並且服務器必須顯式支持它。 JSONP 也並非沒有安全問題,因此讓我們簡要介紹一些其他解決方案。

使用代理

服務器端代碼不受同源策略的約束,可以毫無問題地執行跨源請求。因此,您可以創建某種代理並使用它來檢索您需要的任何數據。參考我們的第一個示例:

/* proxy.php */
$url = "http://run.plnkr.co/plunks/v8xyYN64V4nqCshgjKms/data-1.json";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec ($ch);
curl_close ($ch);
echo $result;
登入後複製

在客戶端:

$.getJSON("https://www.php.cn/link/28db3b5e7bfadf38b792da7192530ac1.com/proxy.php", function(json) {
  console.log(json);
})
登入後複製

但這方法也有缺點。例如,如果第三方站點使用 cookie 進行身份驗證,則此方法將不起作用。

CORS

跨源資源共享 (CORS) 是一個 W3C 規範,允許瀏覽器進行跨域通信。這是通過在響應中包含新的 Access-Control-Allow-Origin HTTP 標頭來實現的。

參考我們的第一個示例,您可以將以下內容添加到 .htaccess 文件(假設為 Apache)以允許來自不同來源的請求:

$.getJSON(
  "http://run.plnkr.co/plunks/v8xyYN64V4nqCshgjKms/data-1.json",
  function(json) { console.log(json); }
);
登入後複製
登入後複製

(如果您運行的服務器不是 Apache,請查看此處:https://www.php.cn/link/819e2e55be8ef0957b56ea94356bfb79

您可以在我們最近的教程之一中了解更多關於 CORS 的信息:深入了解 CORS

結論

JSONP 允許您繞過同源策略,並在某種程度上進行跨域 Ajax 調用。它不是靈丹妙藥,當然也有其問題,但在某些情況下,當從不同來源獲取數據時,它可以證明是無價的。

JSONP 還使您可以從不同的服務中提取各種內容。許多著名的網站提供 JSONP 服務(例如 Flickr),允許您通過預定義的 API 訪問它們的內容。您可以在 ProgrammableWeb API 目錄中找到它們的完整列表。

(以下為FAQ部分,已根據原文進行調整和簡化,避免重複信息)

關於 JSONP 的常見問題解答 (FAQ)

  • JSON 和 JSONP 的主要區別是什麼? JSON 和 JSONP 都是用於處理服務器和 Web 應用程序之間數據的格式。主要區別在於它們處理跨域請求的方式。 JSON 由於同源策略(Web 瀏覽器中實施的安全措施)而無法支持跨域請求。另一方面,JSONP 通過使用填充方法來繞過此策略,允許從與客戶端不同的域的服務器請求數據。

  • JSONP 如何繞過同源策略? JSONP 通過使用填充或“填充請求”方法來繞過同源策略。在此方法中,客戶端通過將回調函數附加到 URL 來請求不同域的服務器的數據。然後,服務器將請求的數據包裝在此函數中並將其發送回客戶端。客戶端執行此函數,從而訪問數據。此方法允許 JSONP 克服同源策略施加的跨域限制。

  • JSONP 安全嗎? 雖然 JSONP 為同源策略提供了一種解決方法,但它確實存在自身的安全風險。由於 JSONP 涉及執行從服務器接收的腳本,因此如果服務器遭到破壞,它會為跨站點腳本 (XSS) 攻擊打開可能性。因此,務必僅與受信任的來源一起使用 JSONP。

  • JSONP 可以處理錯誤響應嗎? 與 JSON 不同,JSONP 沒有內置的錯誤處理。如果 JSONP 請求失敗,瀏覽器不會引發錯誤,並且不會執行回調函數。要處理 JSONP 中的錯誤,您可以實現超時機制,如果在指定時間內未執行回調函數,則會觸發錯誤。

  • 如何使用 jQuery 發出 JSONP 請求? jQuery 提供了一種簡單的方法,可以使用 $.ajax() 方法發出 JSONP 請求。您需要在 $.ajax() 設置中將 dataType 指定為“jsonp”。

  • JSONP 的局限性是什麼? JSONP 有一些限制。它只支持 GET 請求,不支持 POST 或其他 HTTP 方法。它還缺乏錯誤處理功能。此外,由於其繞過同源策略的方法,JSONP 會帶來安全風險。

  • JSONP 現在還使用嗎? 雖然JSONP 過去是進行跨域請求的流行解決方案,但如今由於CORS(跨源資源共享)的出現,其使用頻率較低,CORS 提供了一種更安全、更強大的進行跨域請求的方法。

以上是JQuery的JSONP用示例解釋了的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板