您好,登錄后才能下訂單哦!
這篇文章主要介紹“CORS跨域資源共享問題怎么解決”的相關(guān)知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“CORS跨域資源共享問題怎么解決”文章能幫助大家解決問題。
所謂同源,就是比較兩個頁面的協(xié)議、域名、端口是否相同,相同則是同源,有一個不同就視為不同源。
根據(jù)MDN給出的例子: 下表給出了相對
http://store.company.com/dir/page.html
同源檢測的示例:
URL 結(jié)果 原因 store.company.com/dir2/other.… 成功 store.company.com/dir/inner/a… 成功 單元格 store.company.com/secure.html 失敗 不同協(xié)議 ( https和http ) store.company.com:81/dir/etc.htm… 失敗 不同端口 ( 81和80) news.company.com/dir/other.h… 失敗 不同域名 ( news和store )
瀏覽器為了保證信息安全,規(guī)定了資源訪問使用同源策略。所以,當瀏覽器訪問的資源來自不同源,就會出現(xiàn)跨源資源訪問,即跨域問題。
CORS是瀏覽器解決跨域問題的一種策略,在CORS中,瀏覽器把ajax發(fā)起的請求分為簡單請求和非簡單請求,分別對兩種請求進行處理,再將ajax請求發(fā)往服務(wù)器。
①簡單請求就是滿足以下條件的: 請求方式為這幾種:
GET,POST,HEAD
HTTP頭信息不超出以下幾種:
Accept Accept-Language Content-Language Last-Event-ID content-type只限于三種:text/plain,multipart/form-data,application/x-www-form-urlencoded
對于簡單請求,瀏覽器直接發(fā)出CORS請求,在頭信息中增加一個字段:Origin,表示請求源域名。
例子:
Accept:*/* Accept-Encoding:gzip, deflate, br Accept-Language:zh-CN,zh;q=0.8 Connection:keep-alive Host:localhost:3001 Origin:http://localhost:3000
Origin:http://localhost:3000
字段告訴服務(wù)器請求源是 http://localhost:3000
,服務(wù)器就可以做出相應(yīng)響應(yīng)。
如果服務(wù)器發(fā)現(xiàn)Oringin字段的源不在接受范圍,就會發(fā)送一個正常HTTP回應(yīng),瀏覽器發(fā)現(xiàn)這個回應(yīng)的頭信息中沒有包含Accsess-Control-Allow-Origin字段,就拋出一個錯誤,被XMLHttpRequest的onerror捕獲,即跨域問題出現(xiàn)了。
好了,知道報錯原因,我們就可以從以下方法解決跨域問題了: 概括為一句話:在服務(wù)器設(shè)置接受的源信息。
實例 客戶端請求:
var xhr = new XMLHttpRequest(); var url = 'http://localhost:3000'; xhr.open('GET',url); xhr.send(null); xhr.onreadystatechange = () => { if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { // 如果請求成功 text.innerHTML = xhr.response; } }
服務(wù)器設(shè)置(例子用的express):
var express = require('express'); var test = express(); test.get('/',(req,res) => { res.set('Access-Control-Allow-Origin','http://localhost:3000'); res.header('Access-Control-Allow-Methods', 'GET, POST, PUT'); res.header('Access-Control-Allow-Headers', 'X-Custom-Header'); res.header('Access-Control-Allow-Credentials', 'true'); res.send("hello CORS."); })
如上,服務(wù)器對請求的頭信息進行設(shè)置, Access-Control-Allow-Origin字段表示接受的源,表示接受來自 http://localhost:3000
這個域名的請求。設(shè)置為*表示接受任意域名的請求。
Access-Control-Allow-Methods列舉出服務(wù)器接受的請求方式。 Access-Control-Allow-Headers可以設(shè)置允許請求源的header特殊參數(shù)。 Access-Control-Allow-Credentials該字段可選。它的值是一個布爾值,表示是否允許發(fā)送Cookie。
如此,就可以實現(xiàn)跨域訪問了。
非簡單請求 非簡單請求,我的理解是排除了以上簡單請求的,比如PUT請求。
瀏覽器對于非簡單請求,在發(fā)送正式請求前,會先發(fā)送一個OPTION請求,向服務(wù)器詢問是否接受請求,稱為“預(yù)檢”請求。 如果服務(wù)器接受才會發(fā)送正式請求,否則就報錯。 與簡單請求一樣,服務(wù)器無非也就是判斷請求的域名、頭信息和HTTP動詞等是否在允許范圍。 實例: 客戶端發(fā)送PUT請求:
var xhr = new XMLHttpRequest(); var url = 'http://localhost:3000'; xhr.open('PUT',url); xhr.setRequestHeader('X-Custom-Header', 'value'); xhr.send(); xhr.onreadystatechange = () => { if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { text1.innerHTML = xhr.response; } }
非簡單請求例子中,我設(shè)置了特殊頭信息“X-Custom-Header”,告知服務(wù)器接受這個參數(shù)信息。
在服務(wù)器設(shè)置接受信息:
var express = require('express'); var test = express(); var responsePort = 3001;//服務(wù)器端口 test.all('*', (req, res) => { res.set('Access-Control-Allow-Origin', 'http://localhost:3000'); res.header('Access-Control-Allow-Methods', 'GET, POST, PUT'); res.header('Access-Control-Allow-Headers', 'X-Custom-Header'); res.header('Access-Control-Allow-Credentials', 'true'); res.send("hello CORS."); })
至此,對于兩種請求方式,都可以實現(xiàn)跨域訪問了。 其他解決方法參看如下:
1.CORS(cross-origin resourse sharing)跨域資源共享
2.JSONP
3.document.domain + iframe
4.window.name + iframe
5.postMessage
6.proxy
關(guān)于“CORS跨域資源共享問題怎么解決”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識,可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。