如何使用Nginx解決跨域問(wèn)題詳解
先來(lái)說(shuō)一下什么是同源策略
同源(域名、協(xié)議、端口相同)策略是一種約定,是瀏覽器最核心也是最基本的安全功能,如果缺少了同源策略,瀏覽器的正常功能將受到影響。
什么是跨域?
跨域就是跨域名,跨端口,跨協(xié)議(非同源策略)。
跨域分類
簡(jiǎn)單說(shuō),跨域分為 簡(jiǎn)單跨域 和 復(fù)雜跨域。
簡(jiǎn)單跨域:不會(huì)發(fā)送OPTIONS請(qǐng)求。
復(fù)雜跨域:會(huì)發(fā)送一個(gè)預(yù)檢查OPTIONS請(qǐng)求。
復(fù)雜跨域的條件是:
①、非GET、HEAD、POST請(qǐng)求。
②、POST請(qǐng)求的Content-Type不是application/x-www-form-urlencoded, multipart/form-data, 或text/plain。
③、添加了自定義header,例如Token。
跨域請(qǐng)求瀏覽器會(huì)在Headers中添加Origin,通常情況下不允許用戶修改其值。
Nginx解決跨域問(wèn)題
跨域是前后端分離開(kāi)發(fā)中非常常見(jiàn)的問(wèn)題。無(wú)論用什么編程語(yǔ)言,現(xiàn)在都已經(jīng)很難離開(kāi)Nginx。因此直接在Nginx中處理跨域問(wèn)題有得天獨(dú)厚的優(yōu)勢(shì)。當(dāng)出現(xiàn)跨域問(wèn)題的時(shí)候,只需要給Nginx服務(wù)器配置響應(yīng)的header參數(shù)即可。
只需要在Nginx的配置文件中配置以下參數(shù):
location / { add_header Access-Control-Allow-Origin *; add_header 'Access-Control-Allow-Credentials''true'; # 是否允許后續(xù)請(qǐng)求攜帶cookies,該值只能是true,否則不返回。如果上面的Access-Control-Allow-Origin設(shè)置的是* 而你又需要cookie信息,則 必須設(shè)置這行。 add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS'; add_header Access-Control-Allow-Headers *; if($request_method = 'OPTIONS') { return204; } }
上面的配置代碼即可解決跨域問(wèn)題了,不想深入研究的,看到這里就可以了=-=
解釋
1、Access-Control-Allow-Origin
服務(wù)器默認(rèn)是不被允許跨域的。給Nginx配置Access-Control-Allow-Origin * 后,表示服務(wù)器可以接受所有的請(qǐng)求源(Origin),即接受所有跨域的請(qǐng)求。也就是說(shuō),表示接受任意域名的請(qǐng)求。上面我們這里設(shè)置的是* 這是最簡(jiǎn)單粗暴的方式,但是服務(wù)器出于安全考慮,肯定不會(huì)這么干,而且,如果是*的話,游覽器將不會(huì)發(fā)送cookies數(shù)據(jù)(如果需要攜帶cookies數(shù)據(jù),則需要設(shè)置 'Access-Control-Allow-Credentials:true')。
所以Access-Control-Allow-Origin一般都是設(shè)置為 指定域(也就是指定 某一個(gè)url來(lái)請(qǐng)求我服務(wù)器)的方式。指定域 設(shè)置的方式如下:
add_header Access-Control-Allow-Origin 'www.test.com'; 注意:只能指定一個(gè)域
2、Access-Control-Allow-Headers 是為了防止出現(xiàn)以下錯(cuò)誤:
Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
這個(gè)錯(cuò)誤表示當(dāng)前請(qǐng)求Content-Type的值不被支持。其實(shí)是我們發(fā)起了"application/json"的類型請(qǐng)求導(dǎo)致的。這里涉及到一個(gè)概念:預(yù)檢請(qǐng)求(preflight request)。請(qǐng)看下面"預(yù)檢請(qǐng)求"的介紹。
3、Access-Control-Allow-Methods 是為了防止出現(xiàn)以下錯(cuò)誤:
Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
4、給OPTIONS 添加 204的返回,是為了處理在發(fā)送POST請(qǐng)求時(shí)Nginx依然拒絕訪問(wèn)的錯(cuò)誤
發(fā)送"預(yù)檢請(qǐng)求"時(shí),需要用到方法OPTIONS,所以服務(wù)器需要允許該方法。
預(yù)檢請(qǐng)求(preflight request)
其實(shí)上面的配置涉及到了一個(gè)W3C標(biāo)準(zhǔn):CROS,全稱是跨域資源共享 (Cross-origin resource sharing),它的提出就是為了解決跨域請(qǐng)求的。
跨域資源共享(CORS)標(biāo)準(zhǔn)新增了一組HTTP 首部字段,允許服務(wù)器聲明哪些源站有權(quán)限訪問(wèn)哪些資源。另外,規(guī)范要求,對(duì)那些可能對(duì)服務(wù)器數(shù)據(jù)產(chǎn)生副作用的HTTP 請(qǐng)求方法(特別是 GET 以外的 HTTP 請(qǐng)求,或者搭配某些 MIME 類型的 POST 請(qǐng)求),瀏覽器必須首先使用 OPTIONS 方法發(fā)起一個(gè)預(yù)檢請(qǐng)求(preflight request),從而獲知服務(wù)端是否允許該跨域請(qǐng)求。服務(wù)器確認(rèn)允許之后,才發(fā)起實(shí)際的 HTTP 請(qǐng)求。在預(yù)檢請(qǐng)求的返回中,服務(wù)器端也可以通知客戶端,是否需要攜帶身份憑證(包括 Cookies 和 HTTP 認(rèn)證相關(guān)數(shù)據(jù))。
其實(shí)Content-Type字段的類型為application/json的請(qǐng)求 就是上面所說(shuō)的搭配某些 MIME 類型的 POST 請(qǐng)求,CORS規(guī)定,Content-Type不屬于以下MIME類型的,都屬于預(yù)檢請(qǐng)求:
application``/x-www-form-urlencoded``multipart``/form-data``text``/plain
POST請(qǐng)求中的Content-Type不是上面這三種的其中一種的話,都屬于預(yù)檢請(qǐng)求。(上面也有提到過(guò),就是 復(fù)雜跨域的條件中的第②步)
所以 application/json的請(qǐng)求 會(huì)在正式通信之前,增加一次"預(yù)檢"請(qǐng)求,這次"預(yù)檢"請(qǐng)求會(huì)帶上頭部信息 Access-Control-Request-Headers: Content-Type:
OPTIONS /api/test HTTP/1.1``Origin: http://foo.example``Access-Control-Request-Method: POST``Access-Control-Request-Headers: Content-Type``... 省略了一些
服務(wù)器回應(yīng)時(shí),返回的頭部信息如果不包含Access-Control-Allow-Headers: Content-Type則表示不接受非默認(rèn)的的Content-Type。
即出現(xiàn)以下錯(cuò)誤:
Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
尾聲
解決跨域的解決方案有很多種,最常見(jiàn)也是最傳統(tǒng)的解決方式是使用JSONP的方式。CORS與JSONP的使用目的相同,但是比JSONP更強(qiáng)大。
JSONP只支持GET請(qǐng)求,CORS支持所有類型的HTTP請(qǐng)求。JSONP的優(yōu)勢(shì)在于支持老式瀏覽器,以及可以向不支持CORS的網(wǎng)站請(qǐng)求數(shù)據(jù)。
到此這篇關(guān)于如何使用Nginx解決跨域問(wèn)題的文章就介紹到這了,更多相關(guān)Nginx解決跨域內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
nginx服務(wù)器配置解決ajax的跨域問(wèn)題
本文給大家分享的是一個(gè)nginx服務(wù)器配置解決ajax的跨域問(wèn)題的小技巧,非常的實(shí)用,有相同需求的小伙伴可以參考下2017-03-03封80端口應(yīng)對(duì)策略 Nginx反向代理For WIN2003超級(jí)傻瓜式配置
封80應(yīng)對(duì)策略,Nginx反向代理ForWIN2003超級(jí)傻瓜式配置!2010-03-03NGINX阻止指定ip的請(qǐng)求問(wèn)題及解決方案
web頁(yè)面做了一個(gè)功能,在websocket請(qǐng)求失敗的情況,會(huì)定時(shí)向服務(wù)端進(jìn)行重試進(jìn)行建立連接,這篇文章給大家介紹NGINX阻止指定ip的請(qǐng)求問(wèn)題及解決方案,感興趣的朋友一起看看吧2024-02-02基于Nginx的衍生版服務(wù)器Tengine簡(jiǎn)介
這篇文章主要介紹了基于Nginx的衍生版服務(wù)器Tengine簡(jiǎn)介,本文講解了Nginx的特性、Tengine的特性、架構(gòu)和擴(kuò)展性等內(nèi)容,需要的朋友可以參考下2015-03-03