網(wǎng)站icp備案信息是什么滄州網(wǎng)站建設(shè)推廣
我是這樣打算的,前端用nginx代理,使用80 轉(zhuǎn)443 端口走h(yuǎn)ttps
前端的地址就是http://yumbo.top 或https://yumbo.top
后端服務(wù)地址是:http://yumbo.top:8081
下面是我的完整配置,功能是正常的,加了注釋
user nginx;
worker_processes 1;error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;events {worker_connections 1024;
}http {include /etc/nginx/mime.types;default_type application/octet-stream;log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log /var/log/nginx/access.log main;sendfile on;#tcp_nopush on;keepalive_timeout 65;#gzip on;# include /etc/nginx/conf.d/*.conf;# 以下屬性中以ssl開(kāi)頭的屬性代表與證書(shū)配置有關(guān),其他屬性請(qǐng)根據(jù)自己的需要進(jìn)行配置。server {listen 443 ssl; #SSL協(xié)議訪問(wèn)端口號(hào)為443。此處如未添加ssl,可能會(huì)造成Nginx無(wú)法啟動(dòng)。server_name yumbo.top; #將localhost修改為您證書(shū)綁定的域名,例如:www.example.com。root html;index index.html index.htm;ssl_certificate /etc/nginx/yumbo.top.pem; #替換成您證書(shū)的文件名。ssl_certificate_key /etc/nginx/yumbo.top.key; #替換成您證書(shū)的密鑰文件名。ssl_session_timeout 5m;ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; #使用此加密套件。ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #使用該協(xié)議進(jìn)行配置。ssl_prefer_server_ciphers on; charset utf-8;location / {root /etc/nginx/web; #站點(diǎn)目錄。index index.html index.htm; }#/api是vue中配置的代理路徑location /api/ {add_header Content-Type 'application/json; charset=utf-8';proxy_pass http://yumbo.top:8081/;#后端服務(wù)地址proxy_set_header Origin http://yumbo.top:8081/;#這個(gè)要和后端服務(wù)地址一樣,不然會(huì)出現(xiàn)跨域問(wèn)題proxy_set_header Host $proxy_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;proxy_set_header Access-Control-Allow-Origin *;proxy_set_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';proxy_set_header Access-Control-Allow-Headers 'Content-Type, Authorization';}}server {listen 80;server_name yumbo.top;rewrite ^(.*)$ https://${server_name}$1 permanent; }}
問(wèn)題的發(fā)現(xiàn)
起初nginx沒(méi)有配置好,出現(xiàn)了Invalid CORS request 或者403等之類的錯(cuò)誤。
通過(guò)chrome無(wú)痕窗口訪問(wèn)網(wǎng)站,發(fā)現(xiàn)一個(gè)很奇特的現(xiàn)象,有個(gè)別幾個(gè)接口是好的(login, menu, ringData)。
其他接口都出現(xiàn)了Invalid CORS request 狀態(tài)403
我再三確認(rèn)過(guò)axios 以及 后端springboot項(xiàng)目跨域都是允許的
axios我是這樣配的,所有請(qǐng)求都是通過(guò)這個(gè)axios創(chuàng)建得到的axios對(duì)象,但是detail接口發(fā)現(xiàn)是403 response返回Invalid CORS request
,包括其他接口也都是403,就奇怪了,為什么那幾個(gè)接口為什么沒(méi)有出現(xiàn)跨域?
axios.create({baseURL: (process.env.NODE_ENV === 'production' ? process.env.server : '') + '/api',withCredentials: true,headers})
為了排查這個(gè)問(wèn)題,我用postman去測(cè)接口。
比如去測(cè)這個(gè)detail接口https://yumbo.top/api/dashboard/ringData/detail
發(fā)現(xiàn)postman能成功返回?cái)?shù)據(jù),包括不走nginx代理,直接訪問(wèn)接口http://yumbo.top:8081/api/dashboard/ringData/detail
也都能正常返回?cái)?shù)據(jù)
但是 !!! 部署上服務(wù)器后,就出現(xiàn)了上面截圖 detail 跨域了。非常的困惑
后面看了這篇文章,了解了為什么會(huì)產(chǎn)生跨域:
- 403 Invalid CORS request 跨域問(wèn)題 invalid+cors+request什么意思
一開(kāi)始也沒(méi)認(rèn)真去看這篇文章,文章的內(nèi)容和實(shí)際是有差別的。
有些場(chǎng)景可能多個(gè)因素造成跨域。
通過(guò)postman我確認(rèn)了后端服務(wù)正常,nginx 80 轉(zhuǎn)443 代理正常,接口能通過(guò)https://yumbo.top/api/dashboard/ringData/detail
獲得數(shù)據(jù),但是部署上去的項(xiàng)目就是會(huì)出現(xiàn)下面這種
因?yàn)榭催^(guò)之前提到的哪篇文章,我知道 跨域是根據(jù)http header中的Origin 和 Request URL進(jìn)行比較。
一開(kāi)始我沒(méi)有懷疑是nginx的問(wèn)題,因?yàn)槲野l(fā)現(xiàn)postman能夠拿到接口數(shù)據(jù),那按道理是前端axios與nginx之間的問(wèn)題。
于是我嘗試postman 的header中添加Origin
無(wú)非就是下面這些情況,一個(gè)一個(gè)試
- https://yumbo.top
- http://yumbo.top
- http://yumbo.top:8081
一開(kāi)始呢,我將Origin 值和我nginx地址填的一致https://yumbo.top
,我試了一下,我發(fā)現(xiàn)原先可以拿到接口數(shù)據(jù)的變成了和我chrome訪問(wèn)網(wǎng)站的結(jié)果一樣Invalid CORS request
于是我又試了一下第3種情況 http://yumbo.top:8081
發(fā)現(xiàn)拿到了后端接口數(shù)據(jù)
于是我就回頭找之前出現(xiàn) Invalid CORS request 的請(qǐng)求頭
發(fā)現(xiàn)Request Headers里有這個(gè)字段。于是就明白了,原來(lái)是axios自動(dòng)的給請(qǐng)求頭加了Origin,或者說(shuō)是更底層 XMLRequest自動(dòng)加的。
這個(gè)我們不用改axios,因?yàn)闆](méi)必要改。
通過(guò)上述一系列的嘗試,加上一些文章的內(nèi)容,我們了解到,原來(lái)我遇到的跨域是因?yàn)槲掖淼暮蠖朔?wù)地址http://yumbo.top:8081
而請(qǐng)求頭中的Origin是https://yumbo.top
(瀏覽器看到是是假的,因?yàn)楹竺姹籲ginx轉(zhuǎn)發(fā)了請(qǐng)求)
總結(jié)
得到Invalid CORS request
的結(jié)果是因?yàn)镺rigin的值http://yumbo.top
(前端瀏覽器,axios根據(jù)當(dāng)前域自動(dòng)添加的)和后端代理的接口地址http://yumbo.top:8081
不一致。
我們知道nginx是可以修改請(qǐng)求頭的,只要在nginx轉(zhuǎn)發(fā)的那個(gè)地方加上Origin就可以解決這個(gè)問(wèn)題。
下面是關(guān)鍵信息,只要這2個(gè)一致就行了
location /api/ {proxy_pass http://yumbo.top:8081/;#后端服務(wù)地址proxy_set_header Origin http://yumbo.top:8081/;#這個(gè)要和后端服務(wù)地址一樣,不然會(huì)出現(xiàn)跨域問(wèn)題
}
具體的其他一些關(guān)于nginx的配置,可以參考我前面完整的nginx配置
補(bǔ)充一下,為什么會(huì)出現(xiàn)個(gè)別請(qǐng)求沒(méi)有出現(xiàn)跨域
因?yàn)楹蠖藄pringboot用的是@GetMapping
其他接口我都是用@PostMapping
根據(jù)我之前翻閱的文章知道,針對(duì)一些簡(jiǎn)單請(qǐng)求,比如get請(qǐng)求,或者個(gè)別請(qǐng)求是不會(huì)出現(xiàn)跨域的。