掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
了解下同源策略

1 . DOM 同源策略:即針對于DOM,禁止對不同源頁面的DOM進行操作;如不同域名的 iframe 是限制互相訪問。
2 . XMLHttpRequest 同源策略:禁止使用 XHR 對象向不同源的服務器地址發(fā)起 HTTP 請求。
1. 頁面中的鏈接,重定向以及表單提交(因為表單提交,數(shù)據(jù)提交到action域后,本身頁面就和其沒有關系了,不會管請求結(jié)果,后面操作都交給了action里面的域)是不會受到同源策略限制的。
2. 資源的引入不受限制,但是js不能讀寫加載的內(nèi)容:如嵌入到頁面中的,,,
為什么要跨域限制
1. 用戶登錄了自己的網(wǎng)站頁面 a.com,cookie中添加了用戶標識。
2. 用戶瀏覽了惡意頁面 b.com,執(zhí)行了頁面中的惡意 AJAX 請求代碼。
3. b.com 向 a.com發(fā)起 AJAX HTTP 請求,請求會默認把 a.com對應cookie也同時發(fā)送過去。
4. a.com從發(fā)送的 cookie 中提取用戶標識,驗證用戶無誤,response 中返回請求數(shù)據(jù);數(shù)據(jù)就泄露了。而且由于Ajax在后臺執(zhí)行,這一過程用戶是無法感知的。
跨域決解方案
1. JSONP 跨域:借鑒于 script 標簽不受瀏覽器同源策略的影響,允許跨域引用資源;因此可以通過動態(tài)創(chuàng)建 script 標簽,然后利用 src 屬性進行跨域;
缺點:
1.所有網(wǎng)站都可以拿到數(shù)據(jù),存在安全性問題,需要網(wǎng)站雙方商議基礎token的身份驗證。
2.只能是GET,不能POST。
3.可能被注入惡意代碼,篡改頁面內(nèi)容,可以采用字符串過濾來規(guī)避此問題。
2. 服務器代理:瀏覽器有跨域限制,但是服務器不存在跨域問題,所以可以由服務器請求所要域的資源再返回給客戶端。
3. document.domain、window.name 、location.hash:借助于iframe決解DOM同源策略
4. postMessage:決解DOM同源策略,新方案
5. CORS(跨域資源共享):這里講的重點
CORS(跨域資源共享)
CORS簡單使用
- app.use(async(ctx,next) => {
- ctx.set({
- "Access-Control-Allow-Origin": "http://localhost:8088"
- })
簡單請求和非簡單請求
1. 請求方法是如下之一:
GET
HEAD
POST
2. 所有的Header都只包含如下列表中(沒有自定義header):
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
CORS非簡單請求配置須知
- Origin:請求的源域信息
- Access-Control-Request-Method:接下來的請求類型,如POST、GET等
- Access-Control-Request-Headers:接下來的請求中包含的用戶顯式設置的Header列表
- Access-Control-Allow-Origin:允許跨域的Origin列表
- Access-Control-Allow-Methods:允許跨域的方法列表
- Access-Control-Allow-Headers:允許跨域的Header列表,防止遺漏Header,因此建議沒有特殊需求的情況下設置為*
- Access-Control-Expose-Headers:允許暴露給JavaScript代碼的Header列表
- Access-Control-Max-Age:瀏覽器預檢請求緩存時間,單位為s
CORS完整配置
1. koa配置CORS跨域資源共享中間件:
- const cors = (origin) => {
- return async (ctx, next) => {
- ctx.set({
- "Access-Control-Allow-Origin": origin, //允許的源
- })
- // 預檢請求
- if (ctx.request.method == "OPTIONS") {
- ctx.set({
- 'Access-Control-Allow-Methods': 'OPTIONS,HEAD,DELETE,GET,PUT,POST', //支持跨域的方法
- 'Access-Control-Allow-Headers': '*', //允許的頭
- 'Access-Control-Max-Age':10000, // 預檢請求緩存時間
- // 如果服務器設置Access-Control-Allow-Credentials為true,那么就不能再設置Access-Control-Allow-Origin為*,必須用具體的域名
- 'Access-Control-Allow-Credentials':true // 跨域請求攜帶身份信息(Credential,例如Cookie或者HTTP認證信息)
- });
- ctx.send(null, '預檢請求')
- } else {
- // 真實請求
- await next()
- }
- }
- }
- export default cors
跨域時如何處理cookie
我們知道http時無狀態(tài)的,所以在維持用戶狀態(tài)時,我們一般會使用cookie;
cookie每次同源請求都會攜帶;但是跨域時cookie是不會進行攜帶發(fā)送的;
由于cookie對于不同源是不能進行操作的;這就導致,服務器無法進行cookie設置,瀏覽器也沒法攜帶給服務器(場景:用戶登錄進行登錄操作后,發(fā)現(xiàn)響應中有set-cookie但是,瀏覽器cookie并沒有相應的cookie)
瀏覽器請求設置withCredentials為true即可讓該跨域請求攜帶 Cookie;使用axios配置axios.defaults.withCredentials = true
服務器設置Access-Control-Allow-Credentials=true允許跨域請求攜帶 Cookie

我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流