摘要:把數(shù)據(jù)包裹在一個(gè)客戶(hù)端聲明的本地的回調(diào)函數(shù)中,這樣可以動(dòng)態(tài)加載一個(gè)跨域服務(wù)器數(shù)據(jù)。在本地聲明這個(gè)動(dòng)態(tài)中的回調(diào)函數(shù)名稱(chēng),并且定義該函數(shù),然后通過(guò)參數(shù)傳遞到服務(wù)器。
為什么要跨域
我們都知道在瀏覽器地址欄輸入地址的時(shí)候可以隨便訪問(wèn)一個(gè)頁(yè)面,但是如果你在ajax請(qǐng)求中發(fā)出一個(gè)xhr請(qǐng)求那么因?yàn)闉g覽器安全策略只有同源的服務(wù)器才能處理。這就是同源策略 要求協(xié)議/域名/端口三者完全一致才能訪問(wèn)
例如以下的代碼例子,我們需要獲取服務(wù)器上README.md里面的數(shù)據(jù)
{ status:"sucess", data:{ city:["南京","北京"] } }
本地js代碼如下
如果地址欄是下面這樣
那么我們是可以訪問(wèn)到這個(gè)數(shù)據(jù)文件的
如果我在另外一個(gè)不同源域名下執(zhí)行同樣的代碼例如下面這個(gè)地址
那么就會(huì)出現(xiàn)下面的錯(cuò)誤
這個(gè)錯(cuò)誤的意思說(shuō)白了就是服務(wù)器禁止不同源的頁(yè)面進(jìn)行ajax請(qǐng)求數(shù)據(jù)。
非要獲取這個(gè)數(shù)據(jù)我們應(yīng)該怎么做我們注意到有的網(wǎng)站會(huì)提供cdn服務(wù)我們可以從不同的服務(wù)器添加下面的代碼
這就為我們跨域獲取數(shù)據(jù)提供了可能
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.基本原理我們可以動(dòng)態(tài)生成script標(biāo)簽,把請(qǐng)求的url添加到script標(biāo)簽的src屬性上。把數(shù)據(jù)包裹在一個(gè)客戶(hù)端聲明的本地的回調(diào)函數(shù)中,這樣可以動(dòng)態(tài)加載一個(gè)跨域服務(wù)器數(shù)據(jù)。
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.在本地聲明這個(gè)動(dòng)態(tài)script中的回調(diào)函數(shù)名稱(chēng),并且定義該函數(shù),然后通過(guò)url參數(shù)傳遞到服務(wù)器。服務(wù)器把數(shù)據(jù)包裹成這個(gè)函數(shù)的參數(shù)傳遞回來(lái),跨域就實(shí)現(xiàn)了。
為什么要這么做?以前我也很困惑。你獲取到的數(shù)據(jù)有可能是個(gè)json也有可能是個(gè)純文本,而script標(biāo)簽內(nèi)的內(nèi)容只能是合法的js語(yǔ)句,如果你沒(méi)有用回調(diào)函數(shù)包裹,直接從服務(wù)器傳遞回來(lái)原生數(shù)據(jù)。有可能是一段惡意代碼,或者是非法的js字符,那么瀏覽器就會(huì)報(bào)錯(cuò)或者產(chǎn)生不可預(yù)料的顯示結(jié)果。并且你事先不知道瀏覽器傳遞過(guò)來(lái)的代碼跟你寫(xiě)的有沒(méi)有沖突,是不是完全耦合。只有在本地定義一個(gè)函數(shù)傳遞到服務(wù)器,這樣服務(wù)器用該函數(shù)包裹代碼后傳遞回來(lái)才能跟我們的本地js代碼緊密配合。這樣服務(wù)器傳遞回來(lái)執(zhí)行的代碼就是我們自己定義的函數(shù)(數(shù)據(jù)存在函數(shù)的參數(shù)里),可以很好跟我們自己的代碼配合。這樣頗有Vue Angular子組件向父組件傳遞數(shù)據(jù)的思想
這樣不同域名下的數(shù)據(jù)我們拿到了結(jié)果如下
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/82767.html
摘要:更新了個(gè)版本,最新正式版是語(yǔ)言的下一代標(biāo)準(zhǔn),早已在年月正式發(fā)布。基本不支持移動(dòng)端瀏覽器對(duì)的支持情況版起便可以支持的新特性。比較通用的工具方案有,,,等。 1、ECMAScript是什么? 和 JavaScript 有著怎樣的關(guān)系? 1996 年 11 月,Netscape 創(chuàng)造了javascript并將其提交給了標(biāo)準(zhǔn)化組織 ECMA,次年,ECMA 發(fā)布 262 號(hào)標(biāo)準(zhǔn)文件(ECMA-...
摘要:協(xié)程的歷史說(shuō)來(lái)話(huà)長(zhǎng),要從生成器開(kāi)始講起。我們可以使用把數(shù)據(jù)發(fā)送給協(xié)程函數(shù)??梢钥吹?,在第次接收完數(shù)據(jù)之后,會(huì)產(chǎn)生結(jié)束的異常,因?yàn)槌绦蛄鞒探Y(jié)束了,這是正?,F(xiàn)象。在這個(gè)階段,協(xié)程本質(zhì)上還是由生成器構(gòu)成的。所以,協(xié)程的介紹到這里就結(jié)束啦。 在上一篇對(duì)python并發(fā)編程的理解 中,我簡(jiǎn)單提到了協(xié)程的概念,有一個(gè)錯(cuò)誤需要指出的是,asyncio不全是對(duì)協(xié)程的實(shí)現(xiàn),只是用到了協(xié)程。 協(xié)程的歷史說(shuō)...
摘要:借著產(chǎn)品層面的功能和視覺(jué)升級(jí),我們用對(duì)它進(jìn)行了一次技術(shù)重構(gòu)。前端優(yōu)化是一個(gè)讓人技術(shù)提升的,希望你也能從這里學(xué)到一些東西。年最流行的前端鏈接我們每周會(huì)給多名前端開(kāi)發(fā)者發(fā)送新聞郵件。 面試 -- 網(wǎng)絡(luò) HTTP 現(xiàn)在面試門(mén)檻越來(lái)越高,很多開(kāi)發(fā)者對(duì)于網(wǎng)絡(luò)知識(shí)這塊了解的不是很多,遇到這些面試題會(huì)手足無(wú)措。本篇文章知識(shí)主要集中在 HTTP 這塊。文中知識(shí)來(lái)自 《圖解 HTTP》與維基百科,若有錯(cuò)...
摘要:通過(guò)監(jiān)視資源的變化,并根據(jù)的信息生成記錄寫(xiě)入到中。是唯一保留的容器,依然提供健康檢查。操作會(huì)獲取最新的全量資源與本地狀態(tài)進(jìn)行比較來(lái)產(chǎn)生通知,可以避免網(wǎng)絡(luò)原因?qū)е碌膩G失通知的情況。最后一個(gè)參數(shù)用來(lái)設(shè)置處理事件的回調(diào)。 上一期我們以1.2版本為背景,介紹了K8S的服務(wù)發(fā)現(xiàn)和kube-dns插件的相關(guān)內(nèi)容。有了上一期內(nèi)容作為基礎(chǔ),這期了解最新版本的kube-dns就會(huì)容易很多。 本文主要對(duì)比...
摘要:前言我是,如果你還不認(rèn)識(shí)我,不妨先看看技術(shù)的前世今生一平靜的生活已經(jīng)有一段日子了。傳送門(mén)技術(shù)的前世今生一技術(shù)的前世今生三 前言:我是JavaScript,如果你還不認(rèn)識(shí)我,不妨先看看《Web技術(shù)的前世今生(一)》 平靜的生活已經(jīng)有一段日子了。 這一天,HTML大哥面露不悅地走過(guò)來(lái)問(wèn)我: Js,你是打算和我們分家嗎? 大哥,您這說(shuō)的哪里話(huà),我什么地方做的不對(duì)么?我一臉茫然地回答道。 哼,...
閱讀 1282·2021-11-24 11:16
閱讀 3490·2021-11-15 11:38
閱讀 2020·2021-10-20 13:47
閱讀 628·2021-09-29 09:35
閱讀 2262·2021-09-22 15:17
閱讀 1085·2021-09-07 09:59
閱讀 3440·2019-08-30 13:21
閱讀 2958·2019-08-30 12:47