前端vue開發中的跨域問題解決,以及nginx上線部署。(vue devServer與nginx)


前言

最近做的一個項目中使用了vue+springboot的前后端分離模式
在前端開發的的時候,使用vue cli3的devServer來解決跨域問題
上線部署則是用的nginx反向代理至后台服務所開的端口

正文

開發環境中的跨域

首先,要確定后台服務的ip與端口
這里我的后台開的是
localhost:8081
npm run serve在8080端口

一般我們使用ajax請求的時候,會可以把url ip:port/api 寫在ajax請求的url參數中

this.axios.get("localhost:8081"+ `/bpi/api/DayTradeinfoMarketStatusSearch?ddate=${day}`)

這樣,這個請求就是從localhost:8080發向localhost:8081,端口不同這就遇到了跨域的問題

vue cli WebpackDevServer 解決跨域的方法是通過node開一個服務器進行代理。
前台發向后台服務器的請求,先發向node所開的服務,node服務器以相同的參數向真正的服務器進行請求,再把響應返回給前台。

禁止跨域是瀏覽器的安全策略限制
這里有兩個誤區

  1. ✕ 動態請求就會有跨域的問題
    ✔ 跨域只存在於瀏覽器端,不存在於安卓/ios/Node.js/python/ java等其它環境
    2.✕ 跨域就是請求發不出去了
    ✔ 跨域請求能發出去,服務端能收到請求並正常返回結果,只是結果被瀏覽器攔截了
    詳情請看
    我知道的跨域與安全-李銀成

在vue cli3中的配置
在package.json同級目錄下新建vue.config.js文件

//vue.config.js
module.exports = {
  devServer: {
    proxy: {
      '/bpi': {                                //   以'/bpi'開頭的請求會被代理進行轉發
        target: 'http://localhost:8081',       //   要發向的后台服務器地址  如果后台服務跑在后台開發人員的機器上,就寫成 `http://ip:port` 如 `http:192.168.12.213:8081`   ip為后台服務器的ip
        changeOrigin: true                     
      }
    }
  }
}

ajax請求的寫法

this.axios.get(`/bpi/api/DayTradeinfoMarketStatusSearch?ddate=${day}`)       //相比上面的寫法,這里吧ip和端口去掉了,這樣所發的請求會自動補全為 `localhost:port/api`    (port是npm run serve所開的端口)

這樣,如果打開瀏覽器調試工具的network會發現請求依然發向 localhost:8080而不是后台服務的端口8081
但是沒得關系,node已經幫你向8081端口請求了數據~

上線的時候使用nginx進行部署

使用npm run build命令打包,得到dist文件夾里面的內容就是靜態文件,使用任何一個服務器返回里面的index.html就能在瀏覽器看到頁面。

要注意服務器映射的目錄和vue build的時候的路徑配置
即vue.comfig.js里的 publicPath配置項

//vue.config.js
module.exports = {
  publicPath:'./',   //可以理解成build出來的index.html從哪里找他引用的js、css等文件。默認是"/"從根目錄尋找
  devServer: {
    hotOnly:true,
    disableHostCheck:true,
    proxy: {
      '/bpi': {
        target: 'http://localhost:8081',
        // ws: true,
        // port:8083
        changeOrigin: true
      }
    }
  },
}

publicPath配置為"./" 時:
<script src=js/chunk-vendors.9049ec28.js></script><script src=js/app.379ce736.js></script>

publicPath配置為"/" 時:
<script src=/js/chunk-vendors.9049ec28.js></script><script src=js/app.379ce736.js></script>

nginx的配置
把dist中的內容放到nginx安裝目錄下的html文件夾里(也可以在conf文件夾的nginx.conf中修改要映射的文件夾)

打開nginx.conf

#nginx.conf
#只貼了一些重要內容上來,其他的配置保持默認就好
http {
    server {
        listen       8082;                   //監聽的端口
        server_name  localhost;              

        location / {                         // 表示 以'/'開頭的請求怎樣處理
            root   html;                     //指定root文件夾為 上面提到的html文件夾
            index  index.html;               //返回index.html
        }
        location /bpi{                       // 表示 以'/bpi'開頭的請求 怎樣處理
            proxy_pass http://localhost:8081;     //以同樣的蠶食向這個地址請求,並返回給客戶端
        }

    }
}

這樣,我們訪問localhost:8082的時候,就會把index.html文件返回
雖然network顯示接口是發現8082的,但是會反向代理到8081,這樣就從后台服務器拿到了數據~~~~

vue部署的時候還剩下一個問題

由於vue開發的是單頁面應用(可以看到,一般情況下build出來的dist文件夾里面只有一個html文件)
雖然我們通過vue-router可以實現各種路由,但是在部署之后,頁面一刷新就會碰到404錯誤
這是由於 如果刷新之前 的路由是localhost:8082/bookList/detail ,這樣的話刷新之后向服務器請求的是root文件夾下的bookList文件夾下的detail,而不是根目錄中的index.html了,這就需要做一點小處理
#error_page 404 /index.html; //404的時候就返回index.html

#nginx.conf
#只貼了一些重要內容上來,其他的配置保持默認就好
http {
    server {
        listen       8082;                   //監聽的端口
        server_name  localhost;              

        location / {                         // 表示 以'/'開頭的請求怎樣處理
            root   html;                     //指定root文件夾為 上面提到的html文件夾
            index  index.html;               //返回index.html
        }
        location /bpi{                       // 表示 以'/bpi'開頭的請求 怎樣處理
            proxy_pass http://localhost:8081;     //以同樣的蠶食向這個地址請求,並返回給客戶端
        }

        error_page  404              /index.html;   //404的時候就返回index.html
    }
}

404的時候就返回index.html
這樣進入到index.html后,vue-router再根據地址欄的地址,來決定渲染什么模板,如此一來任性的甲方再怎么刷新也不會報404啦~~


免責聲明!

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



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