一、前言
由於專案是前後端分離,api介面與web前端部署在不同站點當中,因此在前文當中webapi ajax 跨域請求解決方法(cors實現)使用跨域處理方式處理而不用jsonp的方式。
但是在一段時間後,發現一個很奇怪的問題,每次前端發起請求的時候,透過瀏覽器的開發者工具都能看到在network下同一個url有兩個請求,第一條請求的method為options,第二條請求的method才是真正的get或post,並且,第一條請求無資料返回,第二條請求才返回正常的資料。
二、原因
第一個options的請求是由web伺服器處理跨域存取引發的。 options是一種預檢請求,瀏覽器在處理跨域訪問的請求時,如果判斷請求為複雜請求,則會先向伺服器發送一條預檢請求,根據伺服器返回的內容,瀏覽器判斷伺服器是否允許訪問該請求。如果web伺服器採用cors的方式支援跨網域訪問,在處理複雜請求時這個預檢請求是不可避免的。
由於我們的web伺服器採用cors來解決跨域訪問的問題,同時在header中添加了自定義參數以及使用json格式來進行數據交互,導致我們的每次請求都是複雜請求,從而產生每次請求都會發送兩個請求的現象。
產生原因如下:
使用cors解決跨域問題
三、解決方案
3.1 nginx
3.1.1 想法
將前端專案部署在nginx當中,透過代理程式的方式來解決跨域請求問題
3.1.2 實作
3.1.2.1 安裝nginx
windows 下安裝nginx 最簡單,直接下載壓縮包,然後解壓縮後
3.1.2.2 配置nginx
已自帶預設配置,如要部署vue、angular這種單一頁面應用,將打包後的index.html檔案以及dist目錄放到發布目錄中,將路徑複製,用於設定nginx服務指向
設定檔如下:
server { listen 9461; # 监听端口号 server_name localhost 192.168.88.22; # 访问地址 location / { root 项目路径; # 例如:e:/publish/xxx/; index index.html; # 此处用于处理 vue、angular、react 使用h5 的 history时 重写的问题 if (!-e $request_filename) { rewrite ^(.*) /index.html last; break; } } # 代理服务端接口 location /api { proxy_pass http://localhost:9460/api;# 代理接口地址 } }
3.1.2.3 nginx 常用指令
啟動:start nginx
重新載入設定:nginx -s reload
#重新開啟日誌檔案:nginx -s reopen
測試設定檔是否正確: nginx -t [可選:指定路徑]
快速停止:nginx -s stop
有序停止:nginx -s quit
3.1.3 nginx單一頁面應用h5 history url重寫
#支援
#vue、angular、react
原因
##實作單一頁面時,重新整理頁面會產生頁面找不到的問題,所以需要重寫url位址到index.html當中。
注意點
在使用nginx中url重寫的時候,一直報錯如下檢查後,發現if 和( 之間必須有空格。
3.2 other 3.2.1 思路 ##既然要發送預檢請求,是否可以減少預檢請求的次數? 例如可以設定一個有效期,在有效期內不再重複預檢。3.2.2 實現
######可以在服務端預檢完成後加入一個access-control-max-age請求頭來解決這個問題。#########3.2.3 cors 回應欄位說明# ########access-control-allow-methods######該欄位必需,它的值是逗號分隔的一個字串,表示伺服器支援的所有跨域請求的方法。### ###注意,返回的是所有支援的方法,而不單是瀏覽器請求的那個方法。這是為了避免多次"預檢"請求。######access-control-allow-headers## ####如果瀏覽器請求包括access-control-request-headers字段,則access-control-allow-headers字段是必需的。######它也是一個逗號分隔的字串,表示伺服器支援的所有頭資訊字段,不限於瀏覽器在"預檢"中請求的字段。######access-control-allow-credentials######該字段與簡單請求時的含義相同。## ####access-control-max-age######此欄位可選,用來指定本次預檢請求的有效期,單位為秒。上面結果中,有效期是20天(1728000秒),即允許緩存該條回應1728000秒(即20天),在此期間,不用發出另一條預檢請求。###access-control-allow-methods: get, post, put access-control-allow-headers: x-custom-header access-control-allow-credentials: true access-control-max-age: 1728000
以上是Nginx如何解決WebApi跨域二次請求及Vue單頁的問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!