目錄
一、Websocket跨域問題
1.nginx配置
2.VUE CLI代理
3.env.development配置
4.nginx日志
5.解決
一、解決跨域的幾種常用方法
1.Vue CLI代理
2.JSONP
3.WebSocket
4.NGINX解決跨域問題
6.Java解決跨域
二、Vue跨域問題詳解
1. 什么是跨域
2. 跨域的例子
3. 配置代理解決跨域問題
4. 如何配置代理
一、Websocket跨域問題
1.nginx配置
server {listen 8004;server_name 192.168.80.4;client_max_body_size 10M;ssl_protocols TLSv1 TLSv1.1 TLSv1.2;server_tokens off;proxy_buffering on;proxy_buffer_size 1024k;proxy_buffers 100 1024k;proxy_busy_buffers_size 2048k;location / {root im-web;index index.html index.htm;}# IM 接口location /imapi/ {proxy_pass http://192.168.80.4:8888/;}# WebSocketlocation /im/ {proxy_pass http://192.168.80.4:8878/;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";}
}
2.VUE CLI代理
module.exports = {devServer: {proxy: {'/imapi': {target: 'http://192.168.80.4:8004/imapi',changeOrigin: true,ws: false,pathRewrite: {'^/imapi': ''}},'/im': {target: 'http://192.168.80.4:8004/im',changeOrigin: true,ws: true,pathRewrite: {'^/im': ''}}}}
};
3.env.development配置
# 接口請求地址
VUE_APP_BASE_API = '/imapi'# ws地址
VUE_APP_WS_URL = 'ws://192.168.80.4:8004/im'
本地啟動前端vue,端口是8080,訪問服務器上的服務,通過nginx代理,可以登錄,登錄后提示websocket無法連接,ws一直處于連接中
4.nginx日志
5.解決
ngixn日志獲取的ws地址是"GET /im HTTP/1.1",可知道。im后面沒帶斜杠/,所以location的路徑也要不到斜杠,轉發的地址后面也不要帶斜杠,負負得正,
# WebSocket
location /im {proxy_pass http://192.168.80.4:8878;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";
}
實際請求地址http://192.168.80.4:8878/im
WebSocket 在線測試:http://www.websocket-test.com/
一、解決跨域的幾種常用方法
1.Vue CLI代理
可以配置一個代理服務器來轉發 API 請求,繞過瀏覽器的同源策略。vue中通過 Vue CLI 的代理,Vue CLI 提供了一個內置的開發服務器(基于 Webpack Dev Server),可以通過配置代理來解決開發環境中的跨域問題,在vue-cli搭建的項目中有一個配置文件vue.config.js,可以在該文件中進行相應的配置解決開發環境的跨域問題。
在 vue.config.js 文件中進行配置,示例如下:
devServer: {// 1.指定服務的iphost: "192.168.0.128",// 2.指定服務的端口port: 3000,open: true,overlay: {warnings: false,errors: true},// 3.開發環境進行http的代理proxy: {// 匹配 url 路徑的開頭'/api': {// 1.路勁只要是/api開頭的url都代理到下面這個網站。// 例如:'/api/xxxx' 會代理到 https://119.20.224.137/api/xxxxtarget: 'http://119.20.224.137:8201',changeOrigin: true,pathRewrite: { '^/api': '/api/' }}}
}
target: 后端服務器的地址。
changeOrigin: 設置為 true,代理會將請求的 Origin 改為目標地址,避免 CORS 限制。
pathRewrite: 如果前端請求路徑以 /api 開頭,可將其重寫為空,避免在后端 URL 中重復。
對“/api”進行攔截配置,目的是凡是以“/api”開頭的請求url都會將url中的“/api”**的前面添加上我們指定的內容。 例如:
'/api/user/login' ????替換成 ??'http://119.20.224.137:8201/api/user/login'
在上述的例子中,其實 pathRewrite 也可以不寫,例如:
devServer: {open: true,port: 8080,// headers: {},
host: "192.168.0.128",disableHostCheck: true,https: true,proxy: {"/gwkf": { // "/gwky" 是后端的服務名,地址后端以它為開頭的target: "http://119.20.224.137:8201", //你需要訪問的網址 changeOrigin: true,},// 像這種可以配置多個,后端會有多個服務名的情況// 首先我們需要獲取到后端的服務名,就是需要代理的服務名,這個我們可以通過swagger,來找到// 第二點,我們需要找到請求路徑,如果是測試環境(開發環境),就用測試環境、生產環境就用生產環境的路徑。// 然后就在target里面,添加上域名就可以了// changeOrigin 要為true,意思就是:當進行代理時,Host 的源默認會保留// (即Host是瀏覽器發過來的host),// 如果將changeOrigin設置為true,則host會變成target的值;在vue-cli3中,// 默認changeOrigin的值是true,意味著host設置成target,這與cue-cli2不一致,// vue-cli2這個默認值是false。"fast-admin": {target: "https://test-analysis.com/",changeOrigin: true,},"fast-service": {target: "https://test-analysis.com/",changeOrigin: true,},"mth-core-service": {target: "https://test-masterdata.com/",changeOrigin: true,},"mth-core-admin": {target: "https://test-masterdata.com/",changeOrigin: true,},"mth-capital-service": {target: "https://test-analysis.com/",changeOrigin: true,}}
},
示例:Axios 配置
import axios from 'axios';const instance = axios.create({baseURL: '/api', // 開發環境代理前綴withCredentials: true, // 支持跨域攜帶 Cookies
});instance.get('/users').then(res => console.log(res.data));
2.JSONP
如果后端支持 JSONP 跨域請求,可以使用 Vue 中的 JSONP 庫(如 vue-jsonp)來發送跨域請求。
JSONP不推薦JSONP 是一種老舊的跨域解決方案,僅支持 GET 請求,且安全性較低。Vue 項目中一般不建議使用,除非后端僅支持 JSONP。
3.WebSocket
如果需要在 Vue 中與支持 WebSocket 的服務器進行跨域通信,可以使用 WebSocket API 進行連接和通信。WebSocket 不受同源策略的限制。
4.NGINX解決跨域問題
NGINX 解決跨域問題(CORS,Cross-Origin Resource Sharing)通常通過配置響應頭來實現。以下是具體步驟和配置示例:
1. 理解跨域問題
跨域問題是由于瀏覽器的同源策略(Same-Origin Policy)導致的,當前端頁面(如 http://a.com)請求不同域名(如 http://b.com)的資源時,瀏覽器會限制響應,除非服務器明確允許。
2. NGINX 配置解決跨域
在 NGINX 中,可以通過添加 Access-Control-Allow-* 響應頭來解決跨域問題。以下是一個常見的配置方法:
server {listen 80;server_name your_domain.com;location / {# 允許的來源(如前端域名),* 表示允許所有來源add_header 'Access-Control-Allow-Origin' '*' always;# 允許的請求方法add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;# 允許的請求頭add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;# 允許攜帶憑證(如 Cookies)add_header 'Access-Control-Allow-Credentials' 'true' always;# 預檢請求(OPTIONS)的緩存時間add_header 'Access-Control-Max-Age' 1728000 always;# 處理 OPTIONS 預檢請求if ($request_method = 'OPTIONS') {return 204;}# 你的其他配置,如 proxy_pass 或 root# 示例:反向代理到后端proxy_pass http://backend_server;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}
}
配置說明
Access-Control-Allow-Origin: 指定允許的來源域名,* 表示所有域名(生產環境建議指定具體域名以提高安全性)。
Access-Control-Allow-Methods: 指定允許的 HTTP 方法。
Access-Control- Allow-Methods : 指定允許的 HTTP 方法。
Access-Control-Allow-Headers: 指定允許的請求頭。
Access-Control-Allow-Credentials: 如果需要支持 Cookies 或認證信息,設為 true(此時 Access-Control-Allow-Origin 不能為 *)。
Access-Control-Max-Age: 預檢請求的緩存時間,單位為秒。
處理 OPTIONS 請求: 瀏覽器在發送復雜請求(如帶自定義頭或非 GET/POST 請求)前會發送一個 OPTIONS 預檢請求,NGINX 需要返回 204 狀態碼。
3. 注意事項
安全性: 避免盲目使用 *,建議明確指定允許的域名(如 http://frontend.com)。
Credentials 與 Origin: 如果設置了 Access-Control-Allow-Credentials: true,則 Access-Control-Allow-Origin 必須是具體域名,不能是 *。
Credentials 與 Origin: 如果設置了 Access-Control-Allow-Credentials: true,則 Access-Control-Allow-Origin 必須是具體域名,不能是*。
測試: 配置后,使用瀏覽器的開發者工具(Network 面板)檢查響應頭,確保 CORS 頭正確返回。
重啟 NGINX: 修改配置后,運行 nginx -s reload 重載配置。
4. 驗證配置
使用 curl 測試:
curl -I -X OPTIONS http://your_domain.com/api
檢查響應頭是否包含 Access-Control-Allow-*。
瀏覽器測試:打開前端頁面,檢查是否有 CORS 錯誤。
6.Java解決跨域
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@CrossOrigin(origins = "http://frontend.com")
public class Controller {@GetMapping("/users")public String getUsers() {return "Users";}
}
參考:
vue跨域解決的幾種方案【建議收藏】_vue跨域解決方案-CSDN博客
vue解決跨域問題的幾種常用方法(CORS)_vue.js_腳本之家
二、Vue跨域問題詳解
1. 什么是跨域
跨域問題是由于瀏覽器的同源策略(Same-Origin Policy)所導致的,同源策略是瀏覽器的一種安全機制,限制一個域的網頁與另一個域的資源進行交互,即限制了一個源(協議、域名、端口)下的文檔或腳本與另一個源的資源進行交互,也就是瀏覽器向不同源(不用協議、不用域名、不同端口)發送ajax請求會失敗。
2. 跨域的例子
比如,我們啟動的項目,啟動了兩個服務:
前端端口是5173
后端端口是8080
當瀏覽器啟動后,會先發送請求,到前端服務,比如得到一個登錄頁面,這個登錄頁面所在的源,就是http://localhost:5173,在登錄頁面里,嵌套了一段js代碼,里面有一個登錄按鈕,當用戶點擊登錄按鈕時,會發送請求到后端服務http://localhost:8080,此時ajax請求所在的源是5173,但它請求的目標是8080,這個時候,屬于不同的源,由于瀏覽器的同源策略限制,該請求會發送失敗,這種就是跨域問題。
3. 配置代理解決跨域問題
配置代理后,請求就不會從5173直接發向8080,當點擊登錄按鈕,發送異步請求時,會先把請求發向前端服務5173,此時異步請求所在的源就是5173,所以就不會出現跨域問題,再由前端服務5173,轉發到后端服務8080,也就是說,該請求是由服務端發起的,就沒有跨域問題了。
4. 如何配置代理
首先在utils中的請求工具request.js里,把寫固定的路徑修改一下。
utils中的請求工具request.js
示例代碼如下:
//這里邊相當于請求的工具,用來定制請求的實例//導入axios npm install axios
import axios from 'axios';//導入Message消息提示
import { ElMessage } from 'element-plus';//定義一個變量,記錄公共的前綴,baseURL
// const baseURL = 'http://localhost:8080';// 這里的'/api'只是給后臺訪問的請求路徑添加一個標識
const baseURL = '/api';/* axios.create()方法,把baseURL作為參數傳入,該方法返回一個請求的實例instance,以后發送請求時,就不用axios.get了,直接用instance.get就可以 */
const instance = axios.create({baseURL})/* axios提供的攔截器,在請求或響應,被then或catch處理前攔截也就是在請求發出之前,有一個請求攔截器或在響應到達之前,有一個響應攔截器 *///添加響應攔截器(這個攔截器本身就是異步的)
instance.interceptors.response.use(//成功的回調result=>{//判斷業務狀態碼if(result.data.code === 0){return result.data;}//操作失敗ElMessage.error(result.data.msg?result.data.msg:'服務異常');//異步操作的狀態轉換為失敗return Promise.reject(result.data);},//失敗的回調err=>{alert('服務異常');//異步的狀態轉化成失敗的狀態return Promise.reject(err);}
)//把請求的實例instance導出,供其他地方調用
export default instance;
?上述代碼中,只是把const baseURL = ‘http://localhost:8080’;改成了const baseURL = ‘/api’;意思就是,比如以前寫的 const baseURL = ‘http://localhost:8080’;現在改成 const baseURL = ‘/api’;這里的 ‘/api’ 其實就是是給后臺訪問的請求路徑添加一個標識,然后在配置代理里,會把這個 ‘/api’ 替換為我們想要的路徑,api前邊并沒有寫端口號,就會把當前ajax請求所在的源自動拼進去,就相當于寫的http://localhost:5173/api,因為當前ajax代碼所處的源,就是剛才頁面所處的源http://localhost:5173,所以當用戶點擊登錄按鈕時,請求就發送給5173的這個前端服務,兩個源都是5173,所以不會出現跨域,在vite.config.js配置信息里邊,添加 ‘/api’ 的對應配置
這里的配置,才是真正配置代理的,這里才是配置請求路徑和端口號的地方。
示例代碼:
//這里邊寫的是vue項目的配置信息,如端口號等import { fileURLToPath, URL } from 'node:url'import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'// https://vite.dev/config/
export default defineConfig({plugins: [vue(),vueDevTools(),],resolve: {alias: {'@': fileURLToPath(new URL('./src', import.meta.url))},},//server:代表是要做服務相關的配置server: {//proxy: 指的是要配置一些代理proxy: {//這里的'/api'是指:請求路徑中,是否有帶/api這部分的路徑,如果有/api,就對其進行處理'/api': { //獲取路徑中包含了/api的請求//target:指的是,如果要更換源,要更換成誰,就寫誰,這里寫的是后臺服務所在的源target: 'http://localhost:8080',//changeOrigin:指的是,是否要更換換源changeOrigin: true,// rewrite:是路徑的重寫,這里把/api替換為''rewrite: (path) => path.replace(/^\/api/, '')}}}
})
為了更好的理解上邊的配置,舉個例子:比如發送異步請求,路徑是http://localhost:5173/api/user/register,這個路徑中,有 /api,配置信息里的 changeOrigin: true,就會更改源,把源改為target的 ‘http://localhost:8080’,改完后就變成了http://localhost:8080/api/user/register,就是把 /api 前邊的路徑給換了,同時,rewrite重寫路徑,把 /api重寫成空字符串,最后,路徑就是這樣的http://localhost:8080/user/register。
原文鏈接:Vue如何處理瀏覽器跨域問題_vue跨域問題的三種解決方案-CSDN博客