摘要:把數據包裹在一個客戶端聲明的本地的回調函數中,這樣可以動態加載一個跨域服務器數據。在本地聲明這個動態中的回調函數名稱,并且定義該函數,然后通過參數傳遞到服務器。
為什么要跨域
我們都知道在瀏覽器地址欄輸入地址的時候可以隨便訪問一個頁面,但是如果你在ajax請求中發出一個xhr請求那么因為瀏覽器安全策略只有同源的服務器才能處理。這就是同源策略 要求協議/域名/端口三者完全一致才能訪問
例如以下的代碼例子,我們需要獲取服務器上README.md里面的數據
{ status:"sucess", data:{ city:["南京","北京"] } }
本地js代碼如下
如果地址欄是下面這樣
那么我們是可以訪問到這個數據文件的
如果我在另外一個不同源域名下執行同樣的代碼例如下面這個地址
那么就會出現下面的錯誤
這個錯誤的意思說白了就是服務器禁止不同源的頁面進行ajax請求數據。
非要獲取這個數據我們應該怎么做我們注意到有的網站會提供cdn服務我們可以從不同的服務器添加下面的代碼
這就為我們跨域獲取數據提供了可能
var path = require("path") var express = require("express") const app = express() app.use(express.static(path.join(__dirname, "jsonp"))) console.log("> Starting dev server...") app.get("/detail", (req, res) => { let cb = req.query.cb ? req.query.cb : null // console.log("succuess") let readStream = fs.createReadStream(`README.md`) let data = "" readStream.on("data", chunk => { data += chunk }) readStream.on("end", () => { // console.log(data) res.send(`${cb}(${data})`) }) }) var server = app.listen(8888) console.log("server is running at port 8888")
1.基本原理我們可以動態生成script標簽,把請求的url添加到script標簽的src屬性上。把數據包裹在一個客戶端聲明的本地的回調函數中,這樣可以動態加載一個跨域服務器數據。
function jsonp(obj) { let scriptDOM = document.createElement("script") scriptDOM.setAttribute("src", `${obj.url}?cb=${obj.cb}`) window["callback"] = obj.success document.querySelector("body").appendChild(scriptDOM) scriptDOM.onload = function() { window["callback"] = null this.parentNode.removeChild(this) } scriptDOM.onerror = e => { console.log("jsonp error!", e) } } jsonp({ url: "http://localhost:8888/detail", cb: "callback", success: data => { if (data) { console.log("jsonp data", data) } } })
2.在本地聲明這個動態script中的回調函數名稱,并且定義該函數,然后通過url參數傳遞到服務器。服務器把數據包裹成這個函數的參數傳遞回來,跨域就實現了。
為什么要這么做?以前我也很困惑。你獲取到的數據有可能是個json也有可能是個純文本,而script標簽內的內容只能是合法的js語句,如果你沒有用回調函數包裹,直接從服務器傳遞回來原生數據。有可能是一段惡意代碼,或者是非法的js字符,那么瀏覽器就會報錯或者產生不可預料的顯示結果。并且你事先不知道瀏覽器傳遞過來的代碼跟你寫的有沒有沖突,是不是完全耦合。只有在本地定義一個函數傳遞到服務器,這樣服務器用該函數包裹代碼后傳遞回來才能跟我們的本地js代碼緊密配合。這樣服務器傳遞回來執行的代碼就是我們自己定義的函數(數據存在函數的參數里),可以很好跟我們自己的代碼配合。這樣頗有Vue Angular子組件向父組件傳遞數據的思想
這樣不同域名下的數據我們拿到了結果如下
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/82767.html
摘要:更新了個版本,最新正式版是語言的下一代標準,早已在年月正式發布。基本不支持移動端瀏覽器對的支持情況版起便可以支持的新特性。比較通用的工具方案有,,,等。 1、ECMAScript是什么? 和 JavaScript 有著怎樣的關系? 1996 年 11 月,Netscape 創造了javascript并將其提交給了標準化組織 ECMA,次年,ECMA 發布 262 號標準文件(ECMA-...
摘要:協程的歷史說來話長,要從生成器開始講起。我們可以使用把數據發送給協程函數。可以看到,在第次接收完數據之后,會產生結束的異常,因為程序流程結束了,這是正常現象。在這個階段,協程本質上還是由生成器構成的。所以,協程的介紹到這里就結束啦。 在上一篇對python并發編程的理解 中,我簡單提到了協程的概念,有一個錯誤需要指出的是,asyncio不全是對協程的實現,只是用到了協程。 協程的歷史說...
摘要:通過監視資源的變化,并根據的信息生成記錄寫入到中。是唯一保留的容器,依然提供健康檢查。操作會獲取最新的全量資源與本地狀態進行比較來產生通知,可以避免網絡原因導致的丟失通知的情況。最后一個參數用來設置處理事件的回調。 上一期我們以1.2版本為背景,介紹了K8S的服務發現和kube-dns插件的相關內容。有了上一期內容作為基礎,這期了解最新版本的kube-dns就會容易很多。 本文主要對比...
摘要:前言我是,如果你還不認識我,不妨先看看技術的前世今生一平靜的生活已經有一段日子了。傳送門技術的前世今生一技術的前世今生三 前言:我是JavaScript,如果你還不認識我,不妨先看看《Web技術的前世今生(一)》 平靜的生活已經有一段日子了。 這一天,HTML大哥面露不悅地走過來問我: Js,你是打算和我們分家嗎? 大哥,您這說的哪里話,我什么地方做的不對么?我一臉茫然地回答道。 哼,...
閱讀 1211·2021-11-24 11:16
閱讀 3439·2021-11-15 11:38
閱讀 1949·2021-10-20 13:47
閱讀 558·2021-09-29 09:35
閱讀 2206·2021-09-22 15:17
閱讀 1026·2021-09-07 09:59
閱讀 3395·2019-08-30 13:21
閱讀 2918·2019-08-30 12:47