Nginx CORS跨域

場景

咱們的資源來自網絡的四面八方,因此不免須要用上跨域,業界也有很是多跨域的解決方案,此次我是來講說跨域與狀態碼之間的一個問題。html

問題

當咱們的 URL 地址返回的狀態碼是 400、40三、40四、500 的時候,跨域的資源是不會跟隨返回的,也就是說,即使是 Nginx 上配置了 add_header 關鍵字,也不會隨着內容返回而返回。前端

舉個例子說:nginx

add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods *;

當咱們在請求對應地址的時候,理應是會返回已經配置好的頭部信息,可是咱們來看看最終的結果。git

200
HTTP/1.1 200 OK
Server: openresty/1.11.2.2
Date: Fri, 26 Jan 2018 08:46:39 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 558
Last-Modified: Tue, 28 Mar 2017 01:13:24 GMT
Connection: keep-alive
ETag: "58d9b8b4-22e"
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: *
Accept-Ranges: bytes

內容無誤。github

404
HTTP/1.1 404 Not Found
Server: openresty/1.11.2.2
Date: Fri, 26 Jan 2018 08:47:18 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 175
Connection: keep-alive

神奇了,這裏404狀態碼下面竟然自定義的響應頭消失了。跨域

緣由與解決方式

留意 Nginx 文檔上說的:服務器

Adds the specified field to a response header provided that the response code equals 200, 201 (1.3.10), 204, 206, 301, 302, 303, 304, 307 (1.1.16, 1.0.13), or 308 (1.13.0). The value can contain variables.

意思就是說,add_header 只會追加到以上響應狀態碼的響應頭上面。網絡

由於我們的 API 有各類的狀態碼返回,那麼其餘狀態碼下,該怎麼辦? 你們留意文檔上有一個參數。app

Syntax:    add_trailer name value [**always**];
Default:    —
Context:    http, server, location, if in location
This directive appeared in version 1.13.2.

你會發現有個 [always] 參數,那麼這個參數,就是讓你的配置頭,應用在全部的影響上面去。cors

將參數添加進去:

add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Methods * always;

重啓 nginx 服務器後重試一下.

200
HTTP/1.1 200 OK
Server: openresty/1.11.2.2
Date: Fri, 26 Jan 2018 09:01:36 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 558
Last-Modified: Tue, 28 Mar 2017 01:13:24 GMT
Connection: keep-alive
ETag: "58d9b8b4-22e"
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: *
Accept-Ranges: bytes

200請求沒變化,一切正常。

404
HTTP/1.1 404 Not Found
Server: openresty/1.11.2.2
Date: Fri, 26 Jan 2018 09:02:12 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 175
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: *

如今 404 也正確了。咱們的跨域也正是配置完成。

關於 OPTIONS 請求

當咱們前端發起跨域請求的時候,會事先發起一次 OPTIONS 請求,以用來查詢該接口是否支持跨域和對應的請求方法。

在配置方面能夠這麼作。

if ($request_method = OPTIONS) {
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods *;
    add_header Access-Control-Allow-Credentials true;
    return 204;
   }

固然我這裏的 * 這麼用是很差的,你須要對應域名去配置。

另外PHP方面咱們也提供了一個 CORS 的擴展庫,能夠直接在fastd中使用。

github: cors-provider

相關文章
相關標籤/搜索