uni-app+vue3 来说一说前端遇到跨域的解决方案

发布于:2025-07-16 ⋅ 阅读:(13) ⋅ 点赞:(0)

前言:

        在项目开发中,跨域算是常见的问题了,前端来解决跨域也是有多种方式,比如常见的proxy,  uniapp的配置里面也有同样的方法,但是最近我遇到一个很奇怪的问题,不知道是服务端网关限制的原因还是别的原因,就是前端用proxy解决跨域后,接口一直处于pending状态,走不到服务端,所以我使用了nginx来实现跨域解决。这里整理下方法。

跨域问题的产生原因:

指一个页面尝试加载来自跨域(协议、域名、端口)的资源时所遇到的限制和问题,比如:ip/端口不同,产生了跨域问题

小程序与uniapp的内置浏览器无跨域问题:

UniApp 的内置浏览器是基于 WebView 封装的运行环境,默认禁用同源策略

小程序运行在微信/支付宝等平台的沙盒环境中,所有网络请求由客户端原生代码代理,实际请求由平台客户端发出,而非网页浏览器

小程序还有白名单机制
开发者需在后台配置合法域名(如 request 合法域名列表),平台会自动处理跨域问题,对外表现为"无跨域限制"

特性 浏览器 UniApp 内置浏览器/小程序
请求发起方 浏览器 JavaScript 引擎 原生 WebView/客户端环境
网络栈 浏览器网络层 原生网络模块(Android/iOS 原生代码)
同源策略应用 严格强制执行 默认禁用或由平台代理绕过
实际请求地址 直接显示目标 URL 通过客户端代理,隐藏真实端点
CORS 检查

跨域问题前端解决方法:

1、vue项目中使用proxy来解决

新建一个vite.config.js文件

target: // 代理的接口地址

changeOrigin  // 是否允许跨域,默认true

secure      // 是否校验https的限制

rewrite      // 重写地址,

rewrite: path => path.replace(/^\/dev-api/, '')   重写后,路径上没有dev-api,

rewrite: path => path.replace(/^\/dev-api/, 'dev-api')  注释或者这样写,路径上就有dev-api

proxyReq.setHeader // 是可以动态给他在添加请求头,一般不需要

日志打印的:实际转发目标  就是我们代理应该走的实际路径,在编译器或者cmd上看日志

import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'

export default defineConfig({
  plugins: [uni()],
  server: {
		proxy: {
			'/dev-api': {
				target: 'https://cs.he*********', 
				changeOrigin: true,
				secure: false,
				rewrite: path => path.replace(/^\/dev-api/, ''), // 可选:重写路径
				configure: (proxy, options) => {
					proxy.on('proxyReq', (proxyReq, req) => {
						proxyReq.setHeader('Host', 'cs.he*******');
						proxyReq.setHeader('Origin', 'https://cs.he*******');
						proxyReq.setHeader('Referer', 'https://cs.he*******');
						console.log('代理请求路径:', req.url, '=>', proxyReq.path) // 检查请求路径
						console.log('实际转发目标:',
							`${proxyReq.method} ${proxyReq.protocol}//${proxyReq.getHeader('host')}${proxyReq.path}`
						)
					})
					proxy.on('proxyRes', (proxyRes) => {
						console.log('实际响应状态码:', proxyRes.statusCode) // 检查响应状态
					})
				},
			}
		}

  }
})

2、uniapp中全局配置修改

manifest.json中配置

{
  "h5": {
    "devServer": {
      "proxy": {
        "/api": {
          "target": "http://backend-server:8080",
          "changeOrigin": true,
          "pathRewrite": { "^/api": "" }
        }
      }
    }
  }
}

3、nginx解决方案:

如果没有安装过nginx,来看这个:点我
传统的nginx请求配置

1、nginx.conf文件常规配置

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       9005; //你的服务端口
        server_name  localhost; //服务名
        
        
        #下面是与压缩有关的配置,不需要可以不用
        gzip on;            #开启gzip功能
        gzip_min_length  1024;      #响应页面数据上限
        gzip_buffers     4 16k;         #缓存空间大小
        gzip_http_version 1.1;      #http协议版本
        gzip_comp_level  4;         #压缩级别4
        gzip_types       gzip_types text/plain application/x-javascript text/css text/javascript application/x-httpd-php image/jpeg image/gif image/png application/javascript;
        gzip_vary on;       #启用压缩标识
        gzip_static on;     #开启文件预压缩



        #默认服务,也就是你的localhost:9005  默认展示内容
        location / {
			root   F:/project/xiruan/framework/;  #文件名具体地址
            index  	index.html index.htm; #具体文件名
        }

        #代理,这里就指向另一个地址了
        location /dev-api/ {
			rewrite ^ https://cs.heb************;
        }
        

    }
}
我们这里针对性处理,因为有uniapp需求,所以要加很多东西

proxy_pass 后面是我们的代理地址

add_header 通过这种方法添加请求头

proxy_ssl_verify  是https的校验配置,这里直接关闭

/nginx-1.20.2/logs/api_access.log  这是你的日志放得地方,一个是运行日志,一个是报错日志,直接指向你的盘符地址,比如我这里就是对应的是下面的路径:

location /hx-dev/ {
	# 处理 OPTIONS 预检请求,post请求严格
	if ($request_method = 'OPTIONS') {
		add_header 'Access-Control-Allow-Origin' '*';
		add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
		add_header 'Access-Control-Allow-Headers' 'Content-Type, X-Request-Id,Authorization, X-Requested-With, X-Token, App-Id'; # 添加 uni-app 特有头
		add_header 'Access-Control-Max-Age' 1728000; # 20天缓存
		add_header 'Content-Type' 'text/plain; charset=UTF-8';
		add_header 'Content-Length' 0;
		return 204;
	}
	# 解决跨域的核心配置
	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' 'Content-Type, X-Request-Id, Authorization, X-Requested-With, X-Token, App-Id' always;
	add_header 'Access-Control-Allow-Credentials' 'true' always;
			
			
	# 代理配置
	proxy_pass https://cs.h**************/;  #代理的地址,后面可以拼接 /abc这种,根据你需求来
	proxy_set_header Host cs.h*******;       #代理的host
	proxy_set_header X-Real-IP $remote_addr;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	proxy_set_header X-Forwarded-Proto $scheme;
			
	# 处理 uni-app 特有头
	proxy_set_header X-Token $http_x_token;
	proxy_set_header App-Id $http_app_id;
			
	# 日志记录
	access_log /nginx-1.20.2/logs/api_access.log;
	error_log /nginx-1.20.2/logs/api_error.log;
			
	# HTTPS 相关配置
	proxy_ssl_verify off;
	proxy_ssl_server_name on;
			
}

4、node配置请求头方法

app.js中添加跨域请求头
//后端添加请求头解决跨域
app.all('*', function (req, res, next){
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
  res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
  res.header("Access-Control-Allow-Credentials", true);
  res.header("X-Powered-By", ' 3.2.1');
  next();
})


网站公告

今日签到

点亮在社区的每一天
去签到