摘要:同源策略使用發(fā)送網(wǎng)絡(luò)請求有一個條件,那就是同源策略。同源策略要求協(xié)議類型相同等等主機(jī)地址相同或者自己的主機(jī)地址端口號相同等等例如平常使用進(jìn)行調(diào)試的時候,會開一個本地服務(wù)器,但是如果你使用去訪問之類的服務(wù)器你是無法拿到數(shù)據(jù)的。
json和jsonp的關(guān)系
JSON(JavaScript Object Notation, JS 對象標(biāo)記) 是一種輕量級的數(shù)據(jù)交換格式。它基于 ECMAScript (w3c制定的js規(guī)范)的一個子集,采用完全獨立于編程語言的文本格式來存儲和表示數(shù)據(jù)。簡潔和清晰的層次結(jié)構(gòu)使得 JSON 成為理想的數(shù)據(jù)交換語言。 易于人閱讀和編寫,同時也易于機(jī)器解析和生成,并有效地提升網(wǎng)絡(luò)傳輸效率。
JSONP(JSON with Padding)是JSON的一種“使用模式”,可用于解決主流瀏覽器的跨域數(shù)據(jù)訪問的問題。
json和jsonp縮寫只相差一個字母,但是兩者卻完全不同。前者是一種數(shù)據(jù)的表達(dá)方式,后者則是網(wǎng)絡(luò)請求的一種解決方案。
同源策略使用ajax發(fā)送網(wǎng)絡(luò)請求有一個條件,那就是同源策略。
同源策略要求:
協(xié)議類型相同 -> http、https、ftp等等
主機(jī)地址相同 -> https://www.baidu.com/ 或者自己的主機(jī)ip地址
端口號相同 -> 8080、80等等
例如平常使用webstorm進(jìn)行調(diào)試的時候,webstorm會開一個本地服務(wù)器http://localhost:63342/xxxx,但是如果你使用ajax去訪問https://www.baidu.com/之類的服務(wù)器你是無法拿到數(shù)據(jù)的。實際上瀏覽器已經(jīng)拿到數(shù)據(jù),但是做了一層隔離,不給你數(shù)據(jù)。
jsonp原理在說原理之前首先要了解兩個關(guān)于的特點
標(biāo)簽可以使用cdn加速(根據(jù)瀏覽器所在網(wǎng)絡(luò)地區(qū),從最近的服務(wù)器下載js腳本,一般下載框架和庫),那么cdn的服務(wù)器毫無疑問是不同源的。所以,標(biāo)簽可以跨域訪問別的服務(wù)器。
標(biāo)簽是通過src節(jié)點屬性獲取js代碼的,并且獲取到的代碼可以直接執(zhí)行。
在了解了上面的2個的特點之后大概都能猜出來,jsonp就是使用以上兩個特點來實現(xiàn)的,具體的實現(xiàn)方式有2種。
方式一
創(chuàng)建一個函數(shù)(名字隨機(jī)生成,避免多次請求被覆蓋),并且接收一個參數(shù)(服務(wù)器返回的數(shù)據(jù))。
利用標(biāo)簽發(fā)送請求,拼接上callback=方法名參數(shù)。
后端要求接收這個callback參數(shù),拿到方法名后在方法名后拼接(),并且傳入返回的數(shù)據(jù)
這種方式對于php來說就是字符串拼接,但是傳回來的時候則是被js解析成調(diào)用對應(yīng)的方法了。
// php $res = file_get_contents($url); $func = $_GET[callback]; echo callback."(".$res.")";
方式二
使用php或者nodejs去訪問需要跨域的請求
用ajax訪問這個php或者nodejs腳本
方式一示例jsonp無論如何都要后端支持(要么是自己的后端寫的php,要么是別人接口支持jsonp跨域的回調(diào)方法),否則無法使用。
// 1. 創(chuàng)建一個script標(biāo)簽 var script = document.createElement("script"); // 2. 隨機(jī)生成一個方法 // 用時間戳作為種子,這樣隨機(jī)生成的方法名絕對沒有重復(fù)的。 var funcName = "jsonpFunc" + Math.floor(new Date().getTime() * Math.random()); window[funcName] = function (json) { console.log(json); // 把請求完的標(biāo)簽從文檔中移除 document.head.removeChild(script); }; // 3. 拼接請求地址,加上回調(diào) script.src = "http://api.douban.com/v2/movie/in_theaters?callback=" + funcName; // 4. 把script標(biāo)簽放到文檔中,就會發(fā)送請求 document.head.appendChild(script);
封裝一下:
window.myJsonp = function (opt) { // 簡單的容錯 if (!opt || !opt.url) return; opt.callback = opt.callback || "callback"; opt.params = opt.params || {}; opt.callback = opt.callback || function () {}; // 1. 創(chuàng)建一個script標(biāo)簽 var script = document.createElement("script"); // 2. 隨機(jī)生成一個方法 var funcName = "jsonpFunc" + Math.floor(new Date().getTime() * Math.random()); window[funcName] = function (json) { // 5. 把請求完的標(biāo)簽從文檔中移除 document.head.removeChild(script); // 6. 刪除添加到window的方法名稱,避免污染 delete window[funcName]; // 7. 把獲取到的數(shù)據(jù)通過回調(diào)的方式傳出去 opt.callback(json); }; // 3. 拼接請求地址,加上回調(diào)(參數(shù)拼接和get請求一致) var params = ""; for (var key in opt.params) { params += key + "=" + opt.params[key] + "&"; } script.src = opt.url + "?" + params + "callback=" + funcName; // 4. 把script標(biāo)簽放到文檔中,就會發(fā)送請求 document.head.appendChild(script); }; // 使用 myJsonp({ url: "http://api.douban.com/v2/movie/in_theaters", callback: function (json) { console.log(json); } });方式二
待續(xù)。。。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/87226.html
var jsonp = function() { var extend = function(obj, attrs) { for (var name in attrs) { obj[name] = attrs[name]; } }; var jsonp = function() { jsonp_imp.apply(null, arguments); ...
摘要:前提是的方法名與引入的文件方法名一致。簡單描述就是先定義一個方法,然后引入外部調(diào)用這個方法并攜帶數(shù)據(jù)。 JSONP 被用于跨域獲取數(shù)據(jù)。在講解它之前,先講講它與 JSON 之間的區(qū)別 什么是JSON? JSON 是一種基于文本的數(shù)據(jù)交換方式,或者叫做數(shù)據(jù)描述格式。 其優(yōu)點是: 1、基于純文本,跨平臺傳遞極其簡單; 2、Javascript 原生支持,后臺語言幾乎全部支持; 3、輕量級數(shù)...
摘要:為請求指定一個回調(diào)函數(shù)名。這主要用來讓生成一個獨特的函數(shù)名,這樣管理請求更容易,也能方便地提供回調(diào)函數(shù)和錯誤處理。在回調(diào)函數(shù)中,通常我們只需通過判斷請求是否完成,如果已完成,再根據(jù)判斷是否是一個成功的響應(yīng)。 本篇文章借鑒自 博客園文章 原文地址 AJAX即Asynchronous Javascript And XML(異步JavaScript和XML),是指一種創(chuàng)建交互式網(wǎng)頁應(yīng)用的...
摘要:產(chǎn)生跨域問題的原因跨域問題是瀏覽器同源策略限制,當(dāng)前域名的只能讀取同域下的窗口屬性。比如,其中是協(xié)議名,是子域名,是主域名,端口號是,當(dāng)在在頁面中從一個請求數(shù)據(jù)時,如果這個的協(xié)議名子域名主域名端口號任意一個有一個不同,就會產(chǎn)生跨域問題。 產(chǎn)生跨域問題的原因 跨域問題是瀏覽器同源策略限制,當(dāng)前域名的js只能讀取同域下的窗口屬性。 跨域問題產(chǎn)生的場景 當(dāng)要在在頁面中使用js獲取其他網(wǎng)...
閱讀 4756·2021-09-22 16:06
閱讀 2112·2021-09-22 15:22
閱讀 1453·2019-08-30 15:54
閱讀 2539·2019-08-30 15:44
閱讀 2367·2019-08-29 16:31
閱讀 2038·2019-08-29 16:26
閱讀 2355·2019-08-29 12:41
閱讀 758·2019-08-29 12:22