摘要:瀏覽器端需要設(shè)置響應(yīng)頭的,,等字段,指定允許的方法,頭部,源等信息。可以通過前后端約定一個字段名,比如,來傳遞一個函數(shù)名,從而使得前端可以使用對應(yīng)的函數(shù),拿到數(shù)據(jù),處理數(shù)據(jù)。
原文地址:https://github.com/HolyZheng/...
了解幾個跨域的方案,并且通過簡單實踐進(jìn)行體會。
如何實踐?但是,我們?nèi)绾芜M(jìn)行實踐呢?在哪發(fā)請求?向什么服務(wù)器發(fā)請求?很簡單,就在當(dāng)前網(wǎng)頁,打開控制臺,輸入請求的代碼
var url = "http://127.0.0.1:8888/"; var xhr = new XMLHttpRequest(); xhr.open("GET", url, true); xhr.send();
那么我們就可以以當(dāng)前頁面url作為origin,向http://127.0.0.1:8888/ ,發(fā)送請求GET請求了。
同時在本地創(chuàng)建一個node服務(wù)
var http = require("http"); http.createServer(function (request, response) { response.writeHead(200, { "Content-Type": "text/plain" }); response.end("request success!!!"); }).listen(8888); console.log("Server running at http://127.0.0.1:8888/");
這樣我們就有服務(wù)器了,你可以很輕松的跟著這遍文章來實踐了,然后從當(dāng)前網(wǎng)頁發(fā)送get請求到本地服務(wù),理所當(dāng)然跨域了。
ps: github網(wǎng)站不行(本文最初再github上編寫),會引發(fā)csp錯誤,此錯誤是用于防止內(nèi)容注入攻擊的,不得不說,大網(wǎng)站安全措施做得就是好,轉(zhuǎn)戰(zhàn)segmentfault做實踐。1. cors
cors(跨域資源共享 Cross-origin resource sharing),它允許瀏覽器向跨域服務(wù)器發(fā)出XMLHttpRequest請求,從而克服跨域問題,它需要瀏覽器和服務(wù)器的同時支持。
cors 分為兩種請求,簡單請求和非簡單請求,關(guān)于cors的更詳細(xì)介紹,推薦阮一峰老師的跨域資源共享 CORS 詳解,本文注重實踐。簡單請求
正如上方的例子便是一個簡單請求
var url = "http://127.0.0.1:8888/"; var xhr = new XMLHttpRequest(); xhr.open("GET", url, true); xhr.send();
如何解決此案例的跨域問題呢?
瀏覽器端,瀏覽器會自動在請求頭中添加 origin 字段,我們不需要操作。
Request Headers: Origin: https://github.com
服務(wù)端,Access-Control-Allow-Origin屬性,我們需要服務(wù)端設(shè)置此屬性,指定允許的請求源域名,可以通過指定為 *來指定所以域名。后端動起來:
var http = require("http"); http.createServer(function (request, response) { response.writeHead(200, { "Content-Type": "text/plain", "Access-Control-Allow-Origin": "*" }); response.end("request success!!!"); }).listen(8888); console.log("Server running at http://127.0.0.1:8888/");
重啟服務(wù),再嘗試
這次沒有再報錯了,我們看看服務(wù)器放回了什么
nice!跨域成功!
同樣我們在控制臺輸入一下代碼進(jìn)行put(非簡單請求)
var url = "http://127.0.0.1:8888/"; var xhr = new XMLHttpRequest(); xhr.open("PUT", url, true); xhr.send();
毫無意外的報錯
在進(jìn)行非簡單請求的時候,瀏覽器會先發(fā)送一次OPTION請求來“預(yù)檢”(preflight)該請求是否被允許,請求頭中會通過Access-Control-Request-Method,Access-Control-Request-Headers來告訴服務(wù)器我需要用到的方法和字段,服務(wù)器通過返回的頭部信息中的Access-Control-Allow-Origin,Access-Control-Allow-Method來告訴瀏覽器該跨域請求是否被允許。修改后端代碼:
var http = require("http"); http.createServer(function (request, response) { response.writeHead(200, { "Content-Type": "text/plain", "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET, POST, PUT" }); response.end("request success!!!"); }).listen(8888); console.log("Server running at http://127.0.0.1:8888/");
可以看到瀏覽器會先發(fā)送一個預(yù)檢
當(dāng)確認(rèn)允許跨域之后,以后再發(fā)送該請求,就會省去預(yù)檢處理,之間當(dāng)作簡單請求來操作。很明顯,修改了后端代碼后,這次的put請求時成功的。這里就不繼續(xù)上圖了。
cors總結(jié)cors(跨域資源共享 Cross-origin resource sharing),它允許瀏覽器向跨域服務(wù)器發(fā)出XMLHttpRequest請求,從而克服跨域問題,它需要瀏覽器和服務(wù)器的同時支持。
瀏覽器端會自動向請求頭添加origin字段,表明當(dāng)前請求來源。
瀏覽器端需要設(shè)置響應(yīng)頭的Access-Control-Allow-Methods,Access-Control-Allow-Headers,Access-Control-Allow-Origin等字段,指定允許的方法,頭部,源等信息。
請求分為簡單請求和非簡單請求,非簡單請求會先進(jìn)行一次OPTION方法進(jìn)行預(yù)檢,看是否允許當(dāng)前跨域請求。
2. jsonpjsonp的原理就是利用就是利用script標(biāo)簽沒有跨域限制,可以通過script標(biāo)簽的src屬性發(fā)送GET請求。我們繼續(xù)嘗試,先把后端有關(guān)跨域的設(shè)置去掉,并重啟服務(wù)
var http = require("http"); http.createServer(function (request, response) { response.writeHead(200, { "Content-Type": "text/plain" }); response.end("request success!!!"); }).listen(8888); console.log("Server running at http://127.0.0.1:8888/");
打開我們的控制臺輸入一下代碼,利用script標(biāo)簽進(jìn)行jsonp請求
var script = document.createElement("script"); script.type = "text/javascript"; script.src = `http://127.0.0.1:8888/`; document.head.appendChild(script);
可以看到,后端正常的返回了
request success !!!
而且該請求為GET請求
Request URL: http://127.0.0.1:8888/ Request Method: GET Status Code: 200 OK Remote Address: 127.0.0.1:8888 Referrer Policy: no-referrer-when-downgrade
但是我們現(xiàn)在只是成功發(fā)送了一個跨域請求,但是我們不像XMLHttpRequest那樣可以在res.responseText中拿到數(shù)據(jù),通過jsonp我們該怎么拿到請求的數(shù)據(jù)呢?方法就是前后端約定一個callback字段名,來傳遞函數(shù)名,前端通過該函數(shù)來拿到數(shù)據(jù)。前端代碼修改為:
var script = document.createElement("script"); script.type = "text/javascript"; script.src = `http://127.0.0.1:8888/?callback=onBack`; document.head.appendChild(script); function onBack (res) { console.log(JSON.stringify(res)); // 請求完后刪除添加到頁面上的script標(biāo)簽 var head = document.head head.removeChild(script) }
通過callback字段來傳遞函數(shù)名onBack,后端代碼修改為
var http = require("http") var urlTool = require("url") // json 數(shù)據(jù) var data = {"methods": "jsonp", "result": "success"}; http.createServer(function (request, response) { var params = urlTool.parse(request.url, true) console.log(params) response.writeHead(200, { "Content-Type": "text/plain" }); if (params.query && params.query.callback) { // callback(data) var str = `${params.query.callback}(${JSON.stringify(data)})` } response.end(str); }).listen(8888); console.log("Server running at http://127.0.0.1:8888/");
重啟后端服務(wù),并且在控制臺輸入代碼,可以看到結(jié)果:
我們拿到了數(shù)據(jù),并且通過onBack函數(shù)將他輸出到了控制臺上!
總結(jié)jsonp是一種跨域方案,他利用script標(biāo)簽沒有跨域限制的特點,通過script標(biāo)簽的的src屬性發(fā)送GET請求。
可以通過前后端約定一個字段名,比如callback,來傳遞一個函數(shù)名,從而使得前端可以使用對應(yīng)的callback函數(shù),拿到數(shù)據(jù),處理數(shù)據(jù)。
jsonp和cors比較CORS與JSONP的使用目的相同,但是比JSONP更強大。
JSONP只支持GET請求,CORS支持所有類型的HTTP請求。JSONP的優(yōu)勢在于支持老式瀏覽器,以及可以向不支持CORS的網(wǎng)站請求數(shù)據(jù)。
同源策略:同源策略限制了一個源(origin)中加載文本或腳本與來自其它源(origin)中資源的交互方式,這是一個用于隔離潛在惡意文件的重要安全機制。如果兩個頁面擁有 相同 的 協(xié)議(protocol),端口(如果指定),和 主機,那么這兩個頁面就屬于同一個源(origin)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/95869.html
摘要:扯了這么多,自然不是為了吹水,而是要為了引出前端開發(fā)的一個重要的知識點同源策略什么是同源策略出于保護(hù)用戶信息安全的目的,現(xiàn)在的瀏覽器都會實施同源策略這個政策,所謂同源策略指的是不同源的客戶端腳本在沒有明確授權(quán)情況下,不允許讀寫對方的資源。 導(dǎo)語你家的小孩帶了他的朋友來你們的家里玩,你家的小孩如果要在自家屋里拿玩具玩、拿東西吃你自然是不會阻止,但是如果你家小孩的朋友人品不行,亂拿東西吃、...
摘要:扯了這么多,自然不是為了吹水,而是要為了引出前端開發(fā)的一個重要的知識點同源策略什么是同源策略出于保護(hù)用戶信息安全的目的,現(xiàn)在的瀏覽器都會實施同源策略這個政策,所謂同源策略指的是不同源的客戶端腳本在沒有明確授權(quán)情況下,不允許讀寫對方的資源。 導(dǎo)語你家的小孩帶了他的朋友來你們的家里玩,你家的小孩如果要在自家屋里拿玩具玩、拿東西吃你自然是不會阻止,但是如果你家小孩的朋友人品不行,亂拿東西吃、...
摘要:同源策略瀏覽器的一個安全功能,不同源的客戶端腳本在沒有明確授權(quán)的情況下,不能讀寫對方資源。不受同源策略限制的跨域資源的引入是允許的頁面中的鏈接,重定向以及表單提交是不會受到同源策略限制的。1.什么是跨域資源請求? https://www.cnblogs.com/niuli1987/p/10252214.html 同源: 如果兩個頁面的協(xié)議,端口(如果有指定)和域名都相同,則兩個頁面具有相...
摘要:經(jīng)歷了幾場筆試面試,屢次被問到關(guān)于如何實現(xiàn)跨域。轉(zhuǎn)自個人博客關(guān)于跨域什么是跨域一般來說,如果你在開發(fā)中需要進(jìn)行跨域操作從一個非同源網(wǎng)站發(fā)送請求獲取數(shù)據(jù),一般而言,你在瀏覽器控制臺看到的結(jié)果為同源策略說到跨域就不得不提同源策略。 前言 轉(zhuǎn)眼就是秋招季啦。經(jīng)歷了幾場筆試面試,屢次被問到關(guān)于如何實現(xiàn)跨域。老實說,之前都是紙上談兵,也沒有項目需要跨域,甚至覺得這個東西沒什么意義。直到今天項目中...
閱讀 1443·2021-11-22 13:54
閱讀 4324·2021-09-22 15:56
閱讀 1815·2021-09-03 10:30
閱讀 1318·2021-09-03 10:30
閱讀 2086·2019-08-30 15:55
閱讀 1851·2019-08-30 14:13
閱讀 2059·2019-08-29 15:19
閱讀 2341·2019-08-28 18:13