Nginx 解決WebApi跨域二次請求以及Vue單頁面問題

1、前言

因爲項目是先後端分離,API接口與Web前端 部署在不一樣站點當中,所以在前文當中WebApi Ajax 跨域請求解決方法(CORS實現)使用跨域處理方式處理而不用Jsonp的方式。html

可是在一段時間後,發現一個很奇怪的問題,每次前端發起請求的時候,經過瀏覽器的開發者工具都能看到在Network下同一個url有兩條請求,第一條請求的MethodOPTIONS,第二條請求的Method纔是真正的Get或者Post,而且,第一條請求無數據返回,第二條請求才返回正常的數據。前端

2、緣由

第一個OPTIONS的請求是由WEB服務器處理跨域訪問引起的。OPTIONS是一種預檢請求,瀏覽器在處理跨域訪問的請求時,若是判斷請求爲複雜請求,則會先向服務器發送一條預檢請求,根據服務器返回的內容,瀏覽器判斷服務器是否容許訪問該請求。若是WEB服務器採用CORS的方式支持跨域訪問,在處理複雜請求時這個預檢請求是不可避免的。nginx

因爲咱們的WEB服務器採用CORS來解決跨域訪問的問題,同時在header中添加了自定義參數以及使用json格式來進行數據交互,致使咱們的每次請求都是複雜請求,從而產生每次請求都會發送兩條請求的現象。json

產生緣由以下:c#

  • 使用CORS解決跨域問題

3、解決方案

3.1 Nginx

3.1.1 思路

  • 將前端項目部署在Nginx當中,經過代理的方式來解決跨域請求問題

3.1.2 實現

3.1.2.1 安裝 Nginx

Windows 下 安裝 Nginx 最簡單,直接下載壓縮包,而後解壓後後端

3.1.2.2 配置 Nginx

已自帶默認配置,如要部署VueAngular這種單頁面應用,將打包後的index.html文件以及dist目錄放到發佈目錄中,將路徑複製,用於配置Nginx服務指向api

配置文件以下:跨域

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

4、參考文獻

相關文章
相關標籤/搜索