摘要:瀏覽器端需要設置響應頭的,,等字段,指定允許的方法,頭部,源等信息??梢酝ㄟ^前后端約定一個字段名,比如,來傳遞一個函數(shù)名,從而使得前端可以使用對應的函數(shù),拿到數(shù)據(jù),處理數(shù)據(jù)。
原文地址:https://github.com/HolyZheng/...
了解幾個跨域的方案,并且通過簡單實踐進行體會。
如何實踐?但是,我們?nèi)绾芜M行實踐呢?在哪發(fā)請求?向什么服務器發(fā)請求?很簡單,就在當前網(wǎng)頁,打開控制臺,輸入請求的代碼
var url = "http://127.0.0.1:8888/"; var xhr = new XMLHttpRequest(); xhr.open("GET", url, true); xhr.send();
那么我們就可以以當前頁面url作為origin,向http://127.0.0.1:8888/ ,發(fā)送請求GET請求了。
同時在本地創(chuàng)建一個node服務
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ǎng)頁發(fā)送get請求到本地服務,理所當然跨域了。
ps: github網(wǎng)站不行(本文最初再github上編寫),會引發(fā)csp錯誤,此錯誤是用于防止內(nèi)容注入攻擊的,不得不說,大網(wǎng)站安全措施做得就是好,轉戰(zhàn)segmentfault做實踐。1. cors
cors(跨域資源共享 Cross-origin resource sharing),它允許瀏覽器向跨域服務器發(fā)出XMLHttpRequest請求,從而克服跨域問題,它需要瀏覽器和服務器的同時支持。
cors 分為兩種請求,簡單請求和非簡單請求,關于cors的更詳細介紹,推薦阮一峰老師的跨域資源共享 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
服務端,Access-Control-Allow-Origin屬性,我們需要服務端設置此屬性,指定允許的請求源域名,可以通過指定為 *來指定所以域名。后端動起來:
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/");
重啟服務,再嘗試
這次沒有再報錯了,我們看看服務器放回了什么
nice!跨域成功!
同樣我們在控制臺輸入一下代碼進行put(非簡單請求)
var url = "http://127.0.0.1:8888/"; var xhr = new XMLHttpRequest(); xhr.open("PUT", url, true); xhr.send();
毫無意外的報錯
在進行非簡單請求的時候,瀏覽器會先發(fā)送一次OPTION請求來“預檢”(preflight)該請求是否被允許,請求頭中會通過Access-Control-Request-Method,Access-Control-Request-Headers來告訴服務器我需要用到的方法和字段,服務器通過返回的頭部信息中的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ā)送一個預檢
當確認允許跨域之后,以后再發(fā)送該請求,就會省去預檢處理,之間當作簡單請求來操作。很明顯,修改了后端代碼后,這次的put請求時成功的。這里就不繼續(xù)上圖了。
cors總結cors(跨域資源共享 Cross-origin resource sharing),它允許瀏覽器向跨域服務器發(fā)出XMLHttpRequest請求,從而克服跨域問題,它需要瀏覽器和服務器的同時支持。
瀏覽器端會自動向請求頭添加origin字段,表明當前請求來源。
瀏覽器端需要設置響應頭的Access-Control-Allow-Methods,Access-Control-Allow-Headers,Access-Control-Allow-Origin等字段,指定允許的方法,頭部,源等信息。
請求分為簡單請求和非簡單請求,非簡單請求會先進行一次OPTION方法進行預檢,看是否允許當前跨域請求。
2. jsonpjsonp的原理就是利用就是利用script標簽沒有跨域限制,可以通過script標簽的src屬性發(fā)送GET請求。我們繼續(xù)嘗試,先把后端有關跨域的設置去掉,并重啟服務
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標簽進行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標簽 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/");
重啟后端服務,并且在控制臺輸入代碼,可以看到結果:
我們拿到了數(shù)據(jù),并且通過onBack函數(shù)將他輸出到了控制臺上!
總結jsonp是一種跨域方案,他利用script標簽沒有跨域限制的特點,通過script標簽的的src屬性發(fā)送GET請求。
可以通過前后端約定一個字段名,比如callback,來傳遞一個函數(shù)名,從而使得前端可以使用對應的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)。
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/95869.html
摘要:扯了這么多,自然不是為了吹水,而是要為了引出前端開發(fā)的一個重要的知識點同源策略什么是同源策略出于保護用戶信息安全的目的,現(xiàn)在的瀏覽器都會實施同源策略這個政策,所謂同源策略指的是不同源的客戶端腳本在沒有明確授權情況下,不允許讀寫對方的資源。 導語你家的小孩帶了他的朋友來你們的家里玩,你家的小孩如果要在自家屋里拿玩具玩、拿東西吃你自然是不會阻止,但是如果你家小孩的朋友人品不行,亂拿東西吃、...
摘要:扯了這么多,自然不是為了吹水,而是要為了引出前端開發(fā)的一個重要的知識點同源策略什么是同源策略出于保護用戶信息安全的目的,現(xiàn)在的瀏覽器都會實施同源策略這個政策,所謂同源策略指的是不同源的客戶端腳本在沒有明確授權情況下,不允許讀寫對方的資源。 導語你家的小孩帶了他的朋友來你們的家里玩,你家的小孩如果要在自家屋里拿玩具玩、拿東西吃你自然是不會阻止,但是如果你家小孩的朋友人品不行,亂拿東西吃、...
摘要:同源策略瀏覽器的一個安全功能,不同源的客戶端腳本在沒有明確授權的情況下,不能讀寫對方資源。不受同源策略限制的跨域資源的引入是允許的頁面中的鏈接,重定向以及表單提交是不會受到同源策略限制的。1.什么是跨域資源請求? https://www.cnblogs.com/niuli1987/p/10252214.html 同源: 如果兩個頁面的協(xié)議,端口(如果有指定)和域名都相同,則兩個頁面具有相...
閱讀 1457·2021-11-22 13:54
閱讀 4376·2021-09-22 15:56
閱讀 1828·2021-09-03 10:30
閱讀 1326·2021-09-03 10:30
閱讀 2093·2019-08-30 15:55
閱讀 1859·2019-08-30 14:13
閱讀 2066·2019-08-29 15:19
閱讀 2374·2019-08-28 18:13