一.問題背景
前后端分離項(xiàng)目跨域問題,瀏覽器控制臺(tái)報(bào)錯(cuò):No 'Access-Control-Allow-Origin' header is present on the requested resource. 請(qǐng)求方法為OPTIONS,狀態(tài)值為302或403。
本文解決常見的CORS跨域問題,以及,集成CAS 5.3單點(diǎn)登錄內(nèi)嵌頁面時(shí),發(fā)送復(fù)雜請(qǐng)求產(chǎn)生的跨域問題。

二.解決方案
1.Nginx或Tomcat配置
通過Nginx或Tomcat配置,返回相應(yīng)的請(qǐng)求頭,本文采用Tomcat配置方式。
(1)修改conf/web.xml,添加過濾器,若存在其他過濾器添加在最前面。
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.preflight.maxage</param-name>
<param-value>10</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
(2)此時(shí)tomcat8.5以上版本可能會(huì)報(bào)錯(cuò)javax.servlet.ServletException: 當(dāng)allowedOrigins=[*]時(shí),不允許配置supportsCredentials=[true]

去掉20~23行配置,或?qū)ors.allowed.origins配置為允許跨域訪問當(dāng)前服務(wù)器資源的地址,多個(gè)地址用逗號(hào)拼接。
示例:
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>http://cpmp.fulongai.cn,http://192.168.2.154:8888</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.preflight.maxage</param-name>
<param-value>10</param-value>
</init-param>
</filter>
<filter-mapping>
? <filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
至此,大多數(shù)CORS的問題都可以解決了,但對(duì)于復(fù)雜請(qǐng)求仍需進(jìn)一步分析。
2.復(fù)雜請(qǐng)求
對(duì)于復(fù)雜請(qǐng)求,瀏覽器會(huì)先發(fā)送一個(gè)OPTIONS類型的請(qǐng)求進(jìn)行預(yù)檢,服務(wù)端會(huì)根據(jù)請(qǐng)求標(biāo)頭判斷是否允許訪問請(qǐng)求的資源。
舉個(gè)例子:

截圖的中的預(yù)檢請(qǐng)求包含請(qǐng)求表頭如下:
Access-Control-Request-Headers: authorization
Access-Control-Request-Method: GET
Origin: http://192.168.2.154:8888
服務(wù)端應(yīng)允許相應(yīng)的訪問,才能預(yù)檢成功。看看我們之前的配置,GET請(qǐng)求和http://192.168.2.154:8888源都滿足,缺少Access-Control-Request-Headers的authorization支持,因此OPTIONS預(yù)檢返回403,無權(quán)限訪問。
控制臺(tái):

仍然報(bào)錯(cuò)No 'Access-Control-Allow-Origin' header is present on the requested resource.
解決方案:
在web.xml中添加相應(yīng)的配置(14行末尾authorization),問題解決:
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>http://cpmp.fulongai.cn,http://192.168.2.154:8888</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,authorization</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials,Access-Control-Allow-Headers,Access-Control-Allow-Method,Set-Cookie</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.preflight.maxage</param-name>
<param-value>1000</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
重啟tomcat,再次請(qǐng)求,請(qǐng)求標(biāo)頭和響應(yīng)頭相對(duì)應(yīng),預(yù)檢通過,可正常訪問。

至此,問題解決。
參考:
https://tomcat.apache.org/tomcat-8.5-doc/config/filter.html#CORS_Filter文章來源:http://www.zghlxwxcb.cn/news/detail-430946.html
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS文章來源地址http://www.zghlxwxcb.cn/news/detail-430946.html
到了這里,關(guān)于前后端分離項(xiàng)目跨域問題No ‘Access-Control-Allow-Origin‘解決方案的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!