前端如何使用proxyTable和nginx解決跨域問題


最近經常遇到跨域的問題,有時候問題雖然解決了,但是還是會有些模棱兩可概念不清,於是在網上看了一些教程結合實際使用,做個筆記。

1.跨域原因

  • 瀏覽器的限制
  • 跨域(協議/域名/端口的不同)
  • XMLHttpRequest請求

2.解決方案

    1. 瀏覽器禁止檢查(適用於本地寫demo調試)
    1. 后端代碼設置請求參數,允許跨域
    1. 前端不發送XMLHttpRequest請求(如使用JSONP
    1. 前端使用代理轉發的形式

本篇主要介紹如何使用nginx和proxyTable代理的方式解決前端跨域問題

3.proxyTable

案例:假設我們現在本地的開發地址是http://localhost:8080,請求的地址是:http://localhost:8888/static/cnWord.json,我們在代碼中寫出請求如下:

axios.get('http://localhost:8888/static/cnWord.json').then((res)=>{
    console.log('success')
}).catch((res)=>{
    console.log('error')
})

因為端口號的不同,運行結果報了跨域的錯誤

下面介紹如何使用proxyTable(基於vue-cli項目中自帶的服務器配置),解決問題,方便開發環境的調試,文件位置:

我們給proxyTable加上配置:

proxyTable: {
    '/api': {
        target: 'http://localhost:8888',
        changeOrigin: true,
        pathRewrite: {
            '^/api': ''
        }
    }
}
  • target:接口的域名,這里不能直接寫成'http://localhost:8888/static/cnWord.json',親測無效~
  • changeOrigin:開啟代理
  • pathRewrite:可以看到我使用了/api來匹配請求接口的域名,而接口名稱是/static/cnWord.json,因此在實際請求中應該寫成/api/static/cnWord.json,但是我實際請求的地址又是沒有api前綴的,因此需要通過pathRewrite重寫地址,將接口請求的時候前綴去除。

注意修改備注后,需要重新使用 npm run dev 打包編譯項目使配置生效

更改請求:

axios.get('/api/static/cnWord.json',).then((res)=>{
    console.log('success')
}).catch((res)=>{
    console.log('error')
})

此刻控制台打印出

跨域成功!

4.Nginx

上面的方式可以解決我們在vue項目中開發環境的跨域問題,但是無法解決生產環境上的跨域問題,有的時候生產環境上也需要處理跨域問題,這個時候proxyTable就不管用咯,nginx就閃亮登場了~

作用

  • 1) http服務器,可以獨立提供http服務;
  • 2) 虛擬主機:多個域名指向同一個服務器,服務器根據不同的域名把請求轉發到不同的應用服務器;
  • 3) 反向代理:負載均衡,將請求轉發至不同的服務器

安裝與使用

ngixn下載,解壓文件后,啟動命令行開啟web服務器,【注意】nginx的下載包不可放在有中文目錄的文件夾。

  • start nginx 啟動,直接訪問http://localhost/

更多命令:

  • nginx -s stop 快速停止或關閉
  • nginx -s quit 正常停止或關閉
  • nginx -s reload 修改配置文件后重啟

跨域配置項

解決跨域問題,主要是更改nginx的配置文件nginx.conf,通過配置修改地址的轉發。

// 默認配置
    location / {
        root   html; #文件根目錄
        index  index.html index.htm; #默認起始頁
    }

如此,可以將vue打包后的文件放到nginxhtml文件夾中,也可以將root的指向打包后的文件夾,用於快速創建http服務器。還是上面的案例,把proxyTable中的配置全部刪除,然后nginx中增加配置如下:

    location / {
        root   D:\cross-demo\dist #直接指向打包后的文件
        index  index.html index.htm;
    }

    location /api/ {
        proxy_pass http://localhost:8888/; # 將地址代理到api上
    }

訪問http://localhost/ (訪問nginx的http服務)

跨域成功!

虛擬主機配置項

server
    {
        #監聽端口
        listen 80; 

        #服務訪問域名
        server_name localhost; 

        location /api/ { 
            # 反向代理的地址
            proxy_pass http://localhost:8888/; 

            # 對發送給客戶端的URL進行修改
            proxy_redirect off; 
             
            # 后端的Web服務器可以通過X-Forwarded-For獲取用戶真實IP
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;   

            # 允許客戶端請求的最大單文件字節數
            client_max_body_size 10m;  
 
            # 緩沖區代理緩沖用戶端請求的最大字節數      
            client_body_buffer_size 128k;

            # 表示使nginx阻止HTTP應答代碼為400或者更高的應答。
            proxy_intercept_errors on;

            # nginx跟后端服務器連接超時時間
            proxy_connect_timeout 90;

            # 后端服務器數據回傳超時時間
            proxy_send_timeout 90;

            # 連接成功后,后端服務器響應超時時間
            proxy_read_timeout 90;

            # 設置代理服務器(nginx)保存用戶頭信息的緩沖區大小
            proxy_buffer_size 4k;
           
            # 設置用於讀取應答(來自被代理服務器)的緩沖區數目和大小
            # 默認情況也為分頁大小,根據操作系統的不同可能是4k或者8k
            proxy_buffers 4 32k;

            # 高負荷下緩沖大小(proxy_buffers*2)
            proxy_busy_buffers_size 64k;

            # 設置在寫入proxy_temp_path時數據的大小,預防一個工作進程在傳遞文件時阻塞太長
            proxy_temp_file_write_size 64k;
        }       
        
    }
}

常見配置

location /api/ {  
    proxy_pass http://localhost:8888/;
    proxy_pass_request_headers on;
    proxy_set_header Connection "";       
    client_max_body_size    30m;
    client_body_buffer_size 128k; 
    proxy_redirect off;
    proxy_connect_timeout   300;
    proxy_send_timeout      300;
    proxy_read_timeout      300;
    proxy_buffer_size       4k;
    proxy_buffers           4 32k;
    proxy_busy_buffers_size 64k;
    proxy_temp_file_write_size 64k;
    proxy_next_upstream http_502 http_504 error invalid_header; 
}

一般情況下,解決前端跨域直接使用這些配置就足夠了,了解各配置項含義,更易於理解。更改location后的轉發代理地址即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM