首頁 > web前端 > js教程 > CORS跨域資源共享詳細介紹(附程式碼)

CORS跨域資源共享詳細介紹(附程式碼)

不言
發布: 2019-03-12 16:55:31
轉載
2137 人瀏覽過

這篇文章帶給大家的內容是關於CORS跨域資源共享詳細介紹(附程式碼),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

了解下同源策略

來源(origin)*:就是協定、網域名稱和連接埠號碼;同源: 就是來源相同,即協定、網域名稱和連接埠完全相同;同源策略:同源策略是瀏覽器的安全功能,不同來源的客戶端腳本在沒有明確授權的情況下,不能讀寫對方資源;

同源策略的分類:

# DOM 同源策略:即針對於DOM,禁止對不同來源頁面的DOM進行操作;如不同網域的iframe 是限制互相存取。 XMLHttpRequest 同源策略:禁止使用 XHR 物件向不同來源的伺服器位址發起 HTTP 請求。

不受同源策略限制:

頁面中的鏈接,重定向以及表單提交(因為表單提交,資料提交到action網域後,本身頁面就和其沒有關係了,不會管請求結果,後面操作都交給了action裡面的域)是不會受到同源策略限制的。資源的引入不受限制,但是js不能讀寫入載入的內容:如嵌入到頁面中的CORS跨域資源共享詳細介紹(附程式碼)

為什麼要跨域限制

如果沒有DOM 同源策略:那麼就沒有啥xss的研究了,因為你的網站將不是你的網站,而是大家的,誰都可以寫個程式碼來操作你的網站介面

如果沒有XMLHttpRequest 同源策略,那麼就可以很輕易的進行CSRF(跨站請求偽造)攻擊:

用戶登入了自己的網站頁面 a.com,cookie中新增了使用者識別。使用者瀏覽了惡意頁面 b.com,執行了頁面中的惡意 AJAX 請求程式碼。 b.com 向 a.com發起 AJAX HTTP 請求,請求會預設把 a.com對應cookie也同時寄過去。 a.com從發送的 cookie 中提取用戶標識,驗證用戶無誤,response 中返回請求資料;資料就洩露了。而且由於Ajax在後台執行,這個過程使用者是無法感知的。 (附)有了XMLHttpRequest 同源策略就可以限制CSRF攻擊?別忘了還有不受同源策略的:表單提交和資源引入,(安全性問題下期在研究)

跨域決解方案

JSONP 跨域:借鑑於script 標籤不受瀏覽器同源策略的影響,允許跨域引用資源;因此可以透過動態建立script 標籤,然後利用src 屬性進行跨域;

缺點:所有網站都可以拿到數據,存在安全性問題,需要網站雙方商議基礎token的身份驗證。只能是GET,不能POST。可能被注入惡意程式碼,篡改頁面內容,可以採用字串過濾來規避此問題。伺服器代理:瀏覽器有跨網域限制,但是伺服器不存在跨網域問題,所以可以由伺服器請求所要網域的資源再傳回給客戶端。 document.domain、window.name 、location.hash:借助iframe決解DOM同源策略postMessage:決解DOM同源策略,新方案CORS(跨域資源共享):這裡講的重點

CORS(跨域資源共享)

HTML5 提供的標準跨域解決方案,是一個由瀏覽器共同遵循的一套控制策略,透過HTTP的Header來進行互動;主要透過後端來設定CORS配置項。

CORS簡單使用

之前說得CORS跨域,嗯嗯,後端設定Access-Control-Allow-Origin:*|[或具體的網域]就好了;第一次嘗試:

app.use(async(ctx,next) => {
    ctx.set({
        "Access-Control-Allow-Origin": "http://localhost:8088"
})
登入後複製

發現有些請求可以成功,但是有些還是會報錯:

CORS跨域資源共享詳細介紹(附程式碼)

請求被同源策略阻止,預請求的回應沒有通過檢查:http回傳的不是ok?

並且發現發送的是OPTIONS請求:

CORS跨域資源共享詳細介紹(附程式碼)

發現:CORS規格將請求分成兩種類型,一種是簡單請求,另外一種是帶有預檢的非簡單請求

#簡單請求和非簡單請求

瀏覽器發送跨域請求判斷方式:

瀏覽器在發送跨域請求的時候,會先判斷下是簡單請求還是非簡單請求,如果是簡單請求,就先執行服務端程序,然後瀏覽器才會判斷是否跨域;而對於非簡單請求,瀏覽器會在發送實際請求之前先發送OPTIONS的HTTP請求來判斷伺服器是否能接受該跨域請求;如果不能接受的話,瀏覽器會直接阻止接下來實際請求的發生。什麼是簡單請求

請求方法是如下之一:

GETHEADPOST

所有的Header都只包含如下列表(沒有自訂header):

Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma除此之外都是非简单请求

CORS非简单请求配置须知

正如上图报错显示,对于非简单请求,浏览器会先发送options预检,预检通过后才会发送真是的请求;发送options预检请求将关于接下来的真实请求的信息给服务器:

Origin:请求的源域信息
Access-Control-Request-Method:接下来的请求类型,如POST、GET等
Access-Control-Request-Headers:接下来的请求中包含的用户显式设置的Header列表
登入後複製
服务器端收到请求之后,会根据附带的信息来判断是否允许该跨域请求,通过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完整配置

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

cookie:

我们知道http时无状态的,所以在维持用户状态时,我们一般会使用cookie;cookie每次同源请求都会携带;但是跨域时cookie是不会进行携带发送的;

问题:

由于cookie对于不同源是不能进行操作的;这就导致,服务器无法进行cookie设置,浏览器也没法携带给服务器(场景:用户登录进行登录操作后,发现响应中有set-cookie但是,浏览器cookie并没有相应的cookie)

决解:

浏览器请求设置withCredentials为true即可让该跨域请求携带 Cookie;使用axios配置axios.defaults.withCredentials = true服务器设置Access-Control-Allow-Credentials=true允许跨域请求携带 Cookie“积跬步、行千里”—— 持续更新中~,喜欢的话留下个赞和关注哦!

往期经典好文:

服务器(CentOS)安装配置mongodbKoa日志中间件封装开发(log4js)团队合作必备的Git操作使用pm2部署node生产环境

以上是CORS跨域資源共享詳細介紹(附程式碼)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:segmentfault.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板