摘要:前言由于自己平時只做做,并沒有遇到太多跨域問題,今天通過幾個樣例模擬實(shí)現(xiàn)了幾種跨域方式。
前言
由于自己平時只做做demo,并沒有遇到太多跨域問題,今天通過幾個樣例模擬實(shí)現(xiàn)了幾種跨域方式。原文地址 傳送門
本文所有樣例靜態(tài)服務(wù)器基于nodejs實(shí)現(xiàn),代碼親測可用。測試步驟如下:
1.為了實(shí)現(xiàn)跨域訪問的效果,需要下載http-server 作為一個服務(wù)器 npm install http-server。用來掛載靜態(tài)頁面 index.html 。(訪問http://127.0.0.1:8080 顯示index.html頁面)
2.運(yùn)行node創(chuàng)建的靜態(tài)服務(wù)器node server (node搭建靜態(tài)服務(wù)向下翻)
說道跨域可能最先想到就時 jsonp ,實(shí)現(xiàn)原理為:同源策略只限制瀏覽器的行為而不限制js,所以可以將請求寫到 script 標(biāo)簽中。關(guān)鍵代碼如下:
前端發(fā)出跨域請求數(shù)據(jù)后,服務(wù)端去解析該請求:
const data={...} const callback = req.parse(req.url,true).query.callback res.writeHead(200) //最關(guān)鍵的一步,拼接回調(diào)函數(shù)和作為函數(shù)參數(shù)的數(shù)據(jù)data res.end(`${callback}(${JSON.stringfy(data)})`)
瀏覽器接收到服務(wù)端返回的響應(yīng),由于發(fā)起請求的是script,相當(dāng)于直接調(diào)用方法并傳入?yún)?shù)
具體實(shí)現(xiàn)案例(服務(wù)端代碼,node.js)
const url = require("url"); require("http").createServer((req, res) => { const data = { x: 10 }; const callback = url.parse(req.url, true).query.callback res.writeHead(200); //回調(diào)原頁面上函數(shù)處理返回結(jié)果 res.end(`${callback}(${JSON.stringify(data)})`); }).listen(3000, "127.0.0.1"); console.log("服務(wù)器已啟動...");
(前端)
JSONP解決Ajax跨域問題
如果是采用js原生,可以參考傳送門
CORS跨域實(shí)現(xiàn)CORS跨域的思想為:CORS通信和Ajax同源請求沒有區(qū)別,關(guān)鍵在于服務(wù)端的配置。要想實(shí)現(xiàn)CORS通信,服務(wù)端必須要設(shè)置一個自定義頭Access-Control-Origin:""來允許跨域訪問
(樣例僅做了一個最簡單的GET請求demo服務(wù)端代碼)
require("http").createServer((req,res)=>{ res.writeHead(200,{ "Access-Control-Allow-Origin":"http://127.0.0.1:8080" }) res.end("這是來自端口3000的信息,收好了~") }).listen(3000,"127.0.0.1")
(前端代碼)
cors實(shí)現(xiàn)跨域的優(yōu)點(diǎn)是不但能實(shí)現(xiàn) GET , POST 等簡單請求,還能實(shí)現(xiàn) PUT 等非簡單請求跨域
ServerProxy服務(wù)器代理ServerProxy服務(wù)器代理實(shí)現(xiàn)跨域的核心思想是:將跨域請求操作發(fā)送給服務(wù)端,由服務(wù)端代為請求,然后將請求結(jié)返回過來
這里以獲取 CNode:Node.js專業(yè)中文社區(qū) 論壇上一些數(shù)據(jù)為場景。如通過 https://cnodejs.org/api/v1/to...,當(dāng)時因?yàn)椴煌颍阅憧梢詫⒄埱蠛蠖耍屍鋵υ撜埱蟠鸀檗D(zhuǎn)發(fā)。
const url = require("url") const http = require("http") const https = require("https") const server = http.createServer((req,res)=>{ const path = url.parse(req.url).path.slice(1) if(path==="topics"){ https.get("https://cnodejs.org/api/v1/topics", (resp) => { let data="" resp.on("data",chunk=>{ data+=chunk }) resp.on("end",()=>{ res.writeHead(200,{ "Content-Type":"application/json;charset=utf-8" }) res.end(data) }) }) } }).listen(3000,"127.0.0.1") console.log("服務(wù)器已啟動...");postMessage
postMessage是HTML5新增的一項(xiàng)功能,postMessage() 方法允許來自不同源的腳本采用異步方式進(jìn)行有限通信可以實(shí)現(xiàn)跨文本文檔,多窗口,跨域消息傳遞。
利用postMessage不能和服務(wù)端交換數(shù)據(jù),只能在兩個窗口 之間交換數(shù)據(jù)
postMessage(data,origin)方法接收兩個參數(shù)
data:html5規(guī)范中提到該參數(shù)可以是JavaScript的任意基本類型或可復(fù)制的對象.然而并不是所有瀏覽器都做到了這點(diǎn)兒,部分瀏覽器只能處理字符串參數(shù),所以我們在傳遞參數(shù)的時候需要使用JSON.stringify()方法對對象參數(shù)序列化
oringin:字符串參數(shù),指明目標(biāo)窗口的源,協(xié)議+主機(jī)+端口號[+URL],URL會被忽略。這個參數(shù)是為了安全考慮,postMessage()方法只會將message傳遞給指定窗口,當(dāng)然如果愿意也可以建參數(shù)設(shè)置為"*",這樣可以傳遞給任意窗口,如果要指定和當(dāng)前窗口同源的話設(shè)置為"/"
創(chuàng)建一個postMsg.html,創(chuàng)建一個iframe。使用postMessage可以向 http://127.0.0.1:8081 發(fā)送消息,然后監(jiān)聽 message ,可以獲得其他文檔發(fā)來的消息
(創(chuàng)建recieve.html文件)
安全性: postMessage 采用的是 雙向安全機(jī)制 。發(fā)送方發(fā)送數(shù)據(jù)時,會確認(rèn)接收方的源,而監(jiān)聽方監(jiān)聽到 message 事件后,也可以用 event.origin 判斷是否來自于正確可靠的發(fā)送方
webSocket實(shí)現(xiàn)跨域websocket是一中全雙工通信協(xié)議,該協(xié)議不實(shí)行同源政策,只要服務(wù)器支持,就可以通過它進(jìn)行跨源通信
websocket的應(yīng)用實(shí)例:https://segmentfault.com/a/11...
對于主域相同跨子域的情況,可以通過設(shè)置 document.domain 來解決。具體做法是在 example.com/a.html 和 sub.example.com/b.html 兩個文件分別加上 document.domain = example.com
然后通過a.html 文件創(chuàng)建一個iframe,去控制iframe的 window,從而進(jìn)行交互
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/91801.html
摘要:跨域是瀏覽器攔截了服務(wù)器端返回的相應(yīng),不是攔截了請求。通過來實(shí)現(xiàn)跨域使用來實(shí)現(xiàn)跨域可以解決下不能跨域的問題,僅僅支持請求服務(wù)端多加一個參數(shù),在返回數(shù)據(jù)時用把具體的數(shù)據(jù)包裹起來,傳回前端。 項(xiàng)目開發(fā)為了支持web瀏覽器ajax的直接請求,涉及到了跨域的需求,通過學(xué)習(xí)對跨域有了更深入的認(rèn)識,現(xiàn)在總結(jié)一下: 1.跨域說明 跨域指請求和服務(wù)的域不一致,瀏覽器和H5的ajax請求有影響,而對服務(wù)...
摘要:跨域是瀏覽器攔截了服務(wù)器端返回的相應(yīng),不是攔截了請求。通過來實(shí)現(xiàn)跨域使用來實(shí)現(xiàn)跨域可以解決下不能跨域的問題,僅僅支持請求服務(wù)端多加一個參數(shù),在返回數(shù)據(jù)時用把具體的數(shù)據(jù)包裹起來,傳回前端。 項(xiàng)目開發(fā)為了支持web瀏覽器ajax的直接請求,涉及到了跨域的需求,通過學(xué)習(xí)對跨域有了更深入的認(rèn)識,現(xiàn)在總結(jié)一下: 1.跨域說明 跨域指請求和服務(wù)的域不一致,瀏覽器和H5的ajax請求有影響,而對服務(wù)...
摘要:大家都知道可以通過實(shí)現(xiàn)跨域。第一種方式在服務(wù)下添加一個實(shí)現(xiàn)跨域,實(shí)現(xiàn)起來方便。前端服務(wù)和后端服務(wù)在同一臺服務(wù)器上,服務(wù)調(diào)用服務(wù)時,服務(wù)通過負(fù)載均衡進(jìn)入服務(wù)時時,服務(wù)的請求跨域成功,時,服務(wù)的請求跨域失敗。 大家都知道spring boot 可以通過@CrossOrigin實(shí)現(xiàn)跨域。但是在spring cloud 里,如果要粒度那么細(xì)的去控制跨域,這個就太繁瑣了,所以一般來說,會在路由z...
閱讀 3026·2021-11-12 10:36
閱讀 4755·2021-09-22 10:57
閱讀 1569·2021-09-22 10:53
閱讀 2657·2019-08-30 15:55
閱讀 3498·2019-08-29 17:00
閱讀 3356·2019-08-29 16:36
閱讀 2470·2019-08-29 13:46
閱讀 1351·2019-08-26 11:45