亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

CORS怎么設置多域名

發布時間:2021-12-18 10:03:09 來源:億速云 閱讀:352 作者:iii 欄目:大數據

這篇文章主要講解了“CORS怎么設置多域名”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“CORS怎么設置多域名”吧!

CORS

CORS 即跨域資源共享 (Cross-Origin Resource Sharing, CORS)。簡而言之,就是在服務器端的響應中加入幾個標頭,使得瀏覽器能夠跨域訪問資源。

這個響應頭的字段設置就是 Access-Control-Allow-Origin: *

以下是最簡單的一個 CORS 請求

GET / HTTP/1.1
Host: shanyue.tech
Origin: http://shanyue.tech
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36

HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: text/plain; charset=utf-8
Content-Length: 12
Date: Wed, 08 Jul 2020 17:03:44 GMT
Connection: keep-alive
   

預請求與 Options

當一個請求跨域且不是簡單請求時就會發起預請求,也就是 Options。如果沒有預請求,萬一有一個毀滅性的 POST 跨域請求直接執行,雖然最后告知瀏覽器你沒有跨域權限,但是損失已造成,豈不虧大的。

以下條件構成了簡單請求:

  1. Method: 請求的方法是     GET、     POST 及     HEAD
  2. Header: 請求頭是     Content-Type (有限制)、     Accept-Language、     Content-Language
  3. Content-Type: 請求類型是     application/x-www-form-urlencoded、     multipart/form-data 或     text/plain

非簡單請求一般需要開發者主動構造,在項目中常見的 Content-Type: application/jsonAuthorization: <token> 為典型的「非簡單請求」。與之有關的三個字段如下:

  • Access-Control-Allow-Methods: 請求所允許的方法,     「用于預請求 (preflight request) 中」
  • Access-Control-Allow-Headers: 請求所允許的頭,     「用于預請求 (preflight request) 中」
  • Access-Control-Max-Age: 預請求的緩存時間
 

寫一個 CORS Middleware

既然 CORS 原理如此簡單,那就拿起鍵盤寫一個簡單的 CORS 中間件吧,CORS 大致是設置幾個響應頭吧

「關于 CORS 的設置即是對 CORS 相關響應頭的設置,因此了解這些 headers 至關重要。無論對于配置的生產者和消費者,及后端和前端而言,都應該掌握!」

以下是關于 CORS 相關的 response headers 及其釋義

  • Access-Control-Allow-Origin: 可以把資源共享給那些域名,支持 * 及 特定域名
  • Access-Control-Allow-Credentials: 請求是否可以帶 cookie
  • Access-Control-Allow-Methods: 請求所允許的方法,     「用于預請求 (preflight request) 中」
  • Access-Control-Allow-Headers: 請求所允許的頭,     「用于預請求 (preflight request) 中」
  • Access-Control-Expose-Headers: 那些頭可以在響應中列出
  • Access-Control-Max-Age: 預請求的緩存時間

而關于 CORS 的中間件即是使用默認值與配置來設置這些頭,如 koa/cors 需要傳遞以下參數。

/**
 * CORS middleware
 *
 * @param {Object} [options]
 *  - {String|Function(ctx)} origin `Access-Control-Allow-Origin`, default is request Origin header
 *  - {String|Array} allowMethods `Access-Control-Allow-Methods`, default is 'GET,HEAD,PUT,POST,DELETE,PATCH'
 *  - {String|Array} exposeHeaders `Access-Control-Expose-Headers`
 *  - {String|Array} allowHeaders `Access-Control-Allow-Headers`
 *  - {String|Number} maxAge `Access-Control-Max-Age` in seconds
 *  - {Boolean|Function(ctx)} credentials `Access-Control-Allow-Credentials`, default is false.
 *  - {Boolean} keepHeadersOnError Add set headers to `err.header` if an error is thrown
 * @return {Function} cors middleware
 * @api public
 */

// Example
app.use(cors())
   

CORS 如何設置多域名

由上,貌似很簡單,只需要服務端設置一下 Access-Control-Allow-Origin 就可以輕松解決問題,但其中的坑有可能比你想象地要多很多!

先說回 Access-Control-Allow-Origin,它所允許的值只有兩個

  • *: 所有域名
  • shanyue.tech: 特定域名

此時,新問題來了:

?  

CORS 如果需要指定多個域名怎么辦[3]

?  

「如果使用 Access-Control-Allow-Origin: *,則所有的請求不能夠攜帶 cookie,因此這種方案被擯棄。

因此這個問題需要寫代碼來解決,根據請求頭中的 Origin 來設置響應頭 Access-Control-Allow-Origin

  1. 如果請求頭不帶有 Origin,證明未跨域,則不作任何處理
  2. 如果請求頭帶有 Origin,證明跨域,根據 Origin 設置相應的     Access-Control-Allow-Origin: <Origin>
// 獲取 Origin 請求頭
const requestOrigin = ctx.get('Origin');

// 如果沒有,則跳過
if (!requestOrigin) {
  return await next();
}

// 設置響應頭
ctx.set('Access-Control-Allow-Origin', requestOrigin)
 

「但此時會出現一個新的問題:緩存」

 

CORS 與 Vary: Origin

在討論與 Vary 關系時,先拋出一個問題:

?  

如何避免 CDN 為 PC 端緩存移動端頁面[4]

?  

假設有兩個域名訪問 static.shanyue.tech 的跨域資源

  1. foo.shanyue.tech,響應頭中返回     Access-Control-Allow-Origin: foo.shanyue.tech
  2. bar.shanyue.tech,響應頭中返回     Access-Control-Allow-Origin: bar.shanyue.tech

看起來一切正常,但平靜的水面下波濤暗涌:

「如果 static.shanyue.tech 資源被 CDN 緩存,bar.shanyue.tech 再次訪問資源時,因緩存問題,因此此時返回的是 Access-Control-Allow-Origin: foo.shanyue.tech,此時會有跨域問題」

此時,Vary: Origin 就上場了,代表為不同的 Origin 緩存不同的資源,這在各個服務器端 CORS 中間件也能體現出來,如以下幾段代碼

此處是一段 koa 關于 CORS 的處理函數: 詳見 koajs/cors[5]

return async function cors(ctx, next) {
  // If the Origin header is not present terminate this set of steps.
  // The request is outside the scope of this specification.
  const requestOrigin = ctx.get('Origin');

  // Always set Vary header
  // https://github.com/rs/cors/issues/10
  ctx.vary('Origin');
}
 

此處是一段 Go 語言關于 CORS 的處理函數: 詳見 rs/cors[6]

func (c *Cors) handleActualRequest(w http.ResponseWriter, r *http.Request) {
 headers := w.Header()
 origin := r.Header.Get("Origin")

 // Always set Vary, see https://github.com/rs/cors/issues/10
  headers.Add("Vary", "Origin")
}
 

進一步改進相關代碼:

// 獲取 Origin 請求頭
const requestOrigin = ctx.get('Origin');

// 不管有沒有跨域都要設置 Vary: Origin
ctx.set('Vary', 'Origin')

// 如果沒有設置,說明沒有跨域,跳過
if (!requestOrigin) {
  return await next();
}

// 設置響應頭
ctx.set('Access-Control-Allow-Origin', requestOrigin)
 

「那此時是不關于 CORS 的問題就解決了?從中間件處理層面是這樣的,但仍然有一些服務端中間件使用問題及瀏覽器問題」

 

HSTS 與 CORS

HSTS (HTTP Strict Transport Security) 為了避免 HTTP 跳轉到 HTTPS 時遭受潛在的中間人攻擊,由瀏覽器本身控制到 HTTPS 的跳轉。如同 CORS 一樣,它也是有一個服務器的響應頭來控制

Strict-Transport-Security: max-age=5184000
 

此時瀏覽器訪問該域名時,會使用 307 Internal Redirect,無需服務器干涉,自動跳轉到 HTTPS 請求。

「如果前端訪問 HTTP 跨域請求,此時瀏覽器通過 HSTS 跳轉到 HTTPS,但瀏覽器不會給出相應的 CORS 響應頭部,就會發生跨域問題。」

GET / HTTP/1.1
Host: shanyue.tech
Origin: http://shanyue.tech
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36

Access to XMLHttpRequest at 'xxx' from origin 'xxx' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
   

服務器異常處理與跨域異常

當與其他中間件一起工作時,也有可能出現問題,由于不正確的執行順序也可能導致跨域失敗。

假設有一個參數校驗中間件,置于 CORS 中間件上方,由于校驗失敗,并未穿過 CORS 中間件,在前端會報錯跨域失敗,真正的參數校驗問題掩蓋其中。

const Koa = require('koa')
const app = new Koa()
const cors = require('@koa/cors')

// 異常處理中間件
app.use(async (ctx, next) => {
  try {
    await next()
  } catch (e) {
    ctx.body = 'hello, error'
  }
})

// 某一個特定時刻肯定會報錯的中間件
app.use(async (ctx, next) => {
  throw new Error('hello, world')
})

// CORS 中間件
app.use(cors())

app.listen(3000)

感謝各位的閱讀,以上就是“CORS怎么設置多域名”的內容了,經過本文的學習后,相信大家對CORS怎么設置多域名這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

喀什市| 嘉禾县| 芜湖市| 新闻| 伽师县| 聂拉木县| 始兴县| 鄄城县| 井陉县| 米脂县| 青阳县| 深水埗区| 沂源县| 台东县| 牡丹江市| 楚雄市| 湖州市| 广饶县| 秦安县| 罗城| 西贡区| 托里县| 武功县| 定西市| 广汉市| 崇阳县| 五河县| 称多县| 徐闻县| 宝山区| 秀山| 南丰县| 庄河市| 遂宁市| 石楼县| 靖西县| 财经| 江山市| 独山县| 兴安盟| 平江县|