vue跨域问题总结笔记

目录

一、Websocket跨域问题

1.nginx配置

[2.VUE CLI代理](#2.VUE CLI代理)

3.env.development配置

4.nginx日志

5.解决

一、解决跨域的几种常用方法

[1.Vue CLI代理](#1.Vue CLI代理)

2.JSONP

3.WebSocket

4.NGINX解决跨域问题

6.Java解决跨域

二、Vue跨域问题详解

[1. 什么是跨域](#1. 什么是跨域)

[2. 跨域的例子](#2. 跨域的例子)

[3. 配置代理解决跨域问题](#3. 配置代理解决跨域问题)

[4. 如何配置代理](#4. 如何配置代理)


一、Websocket跨域问题

1. nginx配置

bash 复制代码
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/;
	}

	# 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";
	}
}

2.VUE CLI代理

bash 复制代码
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配置

bash 复制代码
# 接口请求地址
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的路径也要不到斜杠,转发的地址后面也不要带斜杠,负负得正,

bash 复制代码
# 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 文件中进行配置,示例如下:

javascript 复制代码
devServer: {
	// 1.指定服务的ip
	host: "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/xxxx
			target: '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 也可以不写,例如:

javascript 复制代码
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 配置

javascript 复制代码
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-* 响应头来解决跨域问题。以下是一个常见的配置方法:

bash 复制代码
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解决跨域

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

示例代码如下:

javascript 复制代码
//这里边相当于请求的工具,用来定制请求的实例

//导入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' 的对应配置

这里的配置,才是真正配置代理的,这里才是配置请求路径和端口号的地方。

示例代码:

javascript 复制代码
//这里边写的是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博客

相关推荐
Virgil_Ye1 年前
浏览器跨域问题笔记
笔记·http·浏览器跨域