前言
簡單整理一下.net core 的跨域問題,這個以前也整理過比較詳細的,故而在此簡單整理一下。
正文
對跨域相對的就是同源,什麼是同源呢?
- 協定相同(http/https)
- 主機(域名)相同
- 端口相同
如果全部滿足這個三個條件就是同源,否者就是跨域。
跨域請求大概是下面這個過程:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiETPwJWZ3ZCMwcTP39zZuBnLuVzRjVXSE9UNJRVTysmaNhHMD1UNBR1TxsGRNpXRE1EejRUT4lERNlHMD5UNjR1T0kEVNZ3YE1EeJRUT5hzQOVzYU9ENJRVT2NmMiNnSywEd5ITW110MaZHetlVdO1GT3lERNl3YXJGc5kHT20ESjBjUIF2Lc12bj5SYphXa5VWen5WY35iclN3Ztl2Lc9CX6MHc0RHaiojIsJye.png)
從上面中看到,這些行為都是浏覽器自己發起的檢驗,而不是我們的使用者的行為。
那麼就有兩點東西就值得關注了。
- 假如a.com和b.com都是我的網站,現在我希望a.com通路b.com的東西。
這時候出現了浏覽器出現報錯,那麼怎麼辦呢?b網站是否應該做什麼呢?
- 安全問題,我就隻希望a.com去通路b.com,其他網站不允許。
上文圖檔中顯示了,浏覽器會發送一個option請求判斷是否允許請求,那麼這個請求是什麼呢?或者它包含什麼呢?
首先這個請求是option,然後其頭部包括。
- origin 請求源
- Access-Control-Request-Method 浏覽器請求的方法,比如說post,get
- Access-Control-Request-Headers 是指我們請求發起的請求頭
那麼我們的伺服器需要響應:
- Access-Control-Allow-Origin 是否允許跨域
- Access-Control-Allow-Credentials 是否允許攜帶我們的認證資訊,比如cookie資訊
- Access-Control-Expose-Headers 允許跨域請求的腳本通路到響應頭的資訊
- Access-Control-Max-Age 有效跨域的時間,如果時間過了浏覽器還有再次過來請求是否可以通過請求
- Access-Control-Allow-Methods 允許的http方法
- Access-Control-Allow-Headers 允許的http頭
也就是說浏覽器需要告訴伺服器我們請求的資訊是怎麼樣的,需要哪個域名來通路、請求的方法是什麼,需要通路的請求的頭部資訊是什麼。
現在假設我們拿到這些資訊了,檢視origin通過,看下請求Access-Control-Request-Method是post也通過,然後檢視一下Access-Control-Request-Headers,比如這個值是X-Custom-token。
那麼如果我們允許使用者請求的header裡面有X-Custom-token的話,那麼在回複裡面Access-Control-Allow-Methods就應該是:Access-Control-Allow-Methods:X-Custom-token。
Access-Control-Request-Headers 上面還是有點繞哈:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Access-Control-Request-Headers 直接看這個。
如上上述滿足origin 和 Access-Control-Request-Method 的話,那麼我在響應包的頭部加入Access-Control-Allow-Origin:true,否則就是在Access-Control-Allow-Origin:false。
這裡說明一下,如果options 請求Access-Control-Request-Headers裡面的值,我們不同意的話,同樣可以傳回Access-Control-Allow-Origin 為true, Access-Control-Allow-Headers可以不傳回,但是在請求的時候會出現使用者自定義的header不會傳輸到我們的背景。
故而,如果Access-Control-Request-Headers 不滿足的時候,個人認為設定可以Access-Control-Allow-Origin為true,這樣表示是允許跨域的,但是自定義的一些header沒有意義故而不傳輸。
同時Access-Control-Allow-Credentials:true,告訴浏覽器請求的時候可以攜帶我們的認證資訊,這個認證資訊一般是Cookie。
Access-Control-Expose-Headers 這個是什麼意思呢? 比如說a.com通路b.com,響應的頭部有一個Good:aaa,也就是自定義頭部。
那麼我們就需要在Access-Control-Expose-Headers寫Good這個頭部資訊(Access-Control-Expose-Headers:Good)運作對a.com的js通路到,否則js無法通路到自定義頭部的。
Access-Control-Max-Age 就是跨域檢測的有效期,就是過了這段時間還是要詢問是否可以請求,因為到時候可能就變卦了。
這個還是很重要的。
Access-Control-Allow-Methods 和 Access-Control-Allow-Headers就是告訴浏覽器,伺服器對這個origin 允許的方法和頭部,如果符合下次就不要再來問一次了。
這些屬性都可以去查https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers。
下面介紹如何設定跨域請求:
配置服務:
services.AddCors(options =>
{
options.AddPolicy("api", builder =>
{
builder.WithOrigins("https://localhost:5000").AllowAnyHeader().AllowCredentials().WithExposedHeaders();
});
});
加入中間件:
app.UseCors();
具體的請求加入屬性頭:
[EnableCors("api")]
[HttpPost]
public IActionResult Pay()
{
return Content(User.FindFirst("name").Value+"買買買");
}
這裡用postman測試一下檢測部分的請求。
下一節
.net core 的緩存問題。