跨域解决方案

119 阅读4分钟

一、npm install 报错 The package-lock.json file was created with an old version of npm, npm WARN o

1.1. 报错原因

npm版本过高,解决方法见第如下,亲测有效可以解决。

1.2. 解决方法

降低npm版本:

npm i npm@6 -g

1.3. 安装淘宝镜像cnpm,用cnpm来安装依赖

  • 先清除缓存
npm cache clean --force

删除项目中的node_modules文件夹

  • 安装淘宝镜像cnpm,用cnpm来安装依赖
npm install -g cnpm --registry=https://registry.npm.taobao.org
  • 最后再执行
cnpm install

二、浏览器跨域

2.1 react 跨域

2.11 安装依赖http-proxy-middleware

sudo npm install http-proxy-middleware   // MAC
npm install http-proxy-middleware   // Windows

2.12 在src下创建配置文件:src/setupProxy.js

const { createProxyMiddleware } = require('http-proxy-middleware')
//引入'http-proxy-middleware'不生效则用以下方法引入
//const proxy = require('http-proxy-middleware')

module.exports = function (app) {
  app.use(
    createProxyMiddleware('/api1', { // 遇见‘/api1’这个前缀的请求,就会触发这个代理
      target: 'http://127.0.0.1:5000',  // 请求转发的目标(target)地址
      changeOrigin: true,  // 默认值为false,控制服务器收到的请求头中Host字段的值
      /*
      	changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
      	changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:3000
      	changeOrigin默认值为false,但我们一般将changeOrigin值设为true
      */
      pathRewrite: { '^/api1': '' }  
      //去除请求前缀,保证交给后台服务器的是正常请求地址(必须配置)
    }),
    createProxyMiddleware('/api2', {
      target: 'http://127.0.0.1:5001',
      changeOrigin: true,
      pathRewrite: { '^/api2': '' }
    })
  )
}

2.13 在请求的url中添加【前缀】使用:

封装接口请求则用dev还是pro环境添加,dev环境添加前缀

getStudentData = () => {
    axios.get('/api1/students')
      .then(response => {
        console.log('成功了', response.data)
      }, error => {
        console.log('失败了', error)
      }
      )
}
  
getCarData = () => {
    axios.get('/api2/cars')
      .then(response => {
        console.log('成功了', response.data)
      }, error => {
        console.log('失败了', error)
      }
      )
}

2.3 vue 跨域

2.31 vue项目目录下新建vite.config.js

参考devServer.proxy

import { defineConfig } from 'vite'

// https://vitejs.dev/config/
export default defineConfig({
  server: {
    //配置运行Network地址
    host:'0.0.0.0',
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^/api/, '')
      }
    },
  }
})

2.32 在请求的url中添加【前缀】使用

封装接口请求则用dev还是pro环境添加,dev环境添加前缀

let BASE_URL = 'http://localhost/'
constructor(baseURL, timeout = 10000) {
  this.instance = axios.create({
    baseURL: process.env.NODE_ENV === 'development' ? '/api' : BASE_URL,
    timeout,
    headers: {
      'Content-Type': 'application/json'
    }
  })
}

2.4 uniapp 跨域

2.41 manifest.json中设置

"h5" : {
    "https" : false,
    "devServer" : {
                    "port":8081,
        "proxy" : {
            "/api" : {
                "target" : "http://127.0.0.1/",
                "changeOrigin" : true,
                "pathRewrite" : {
                    "^/api" : ""
                }
            }
        }
    }
}

2.42 在请求的url中添加【前缀】使用(同上 2.32)

2.5 后端跨域:cors解决

2.51 注解解决跨域

cors解决跨域,前端不用做任何事,后端或者服务器去操作,在服务器里面返回相应的时候加几个响应头,cors解决跨域才是真正意义上的解决跨域,但是在开发中,这个响应头不是随便配置的,如果随意配置,就会造成一个问题就算任何人都能找服务器要数据,存在一些安全风险

在后端的controller或某个具体方法上可以加上@CrossOrigin注解解决跨域

image.png 加完注解后,重启后端服务器再访问,问题解决

@CrossOrigin这个注解默认是解决全部路径的跨域,有时候一些参数需要自己设置,否则可能会有安全隐患

image.png

2.52 全局配置跨域

如果使用注解,那么我们需要在每一个controller或者方法上都要加上注解才能解决跨域的问题 可以使用全局配置跨域,y一劳永逸,代码如下:

注意:一定不要忘了使用@Configuration注解配置到项目中,否则无效,具体的一些参数或者路径,根据自身需求设置即可

image.png

package com.wyh.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsMapping implements WebMvcConfigurer {

    @Override
    /**
     * 重新跨域支持方法
     * CorsRegistry  开启跨域注册
     */
    public void addCorsMappings(CorsRegistry registry) {
        //addMapping 添加可跨域的请求地址
        registry.addMapping("/**")
                //设置跨域 域名权限 规定由某一个指定的域名+端口能访问跨域项目
                .allowedOrigins("*")
                //是否开启cookie跨域
                .allowCredentials(false)
                //规定能够跨域访问的方法类型
                .allowedMethods("GET","POST","DELETE","PUT","OPTIONS")
                //添加验证头信息  token
                //.allowedHeaders()
                //预检请求存活时间 在此期间不再次发送预检请求
                .maxAge(3600);
    }
}

2.53 实现 WebMvcConfigurer 接口,重写 addCorsMappings 方法

@Configuration
public class CorsConfiguration implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*")//允许哪些域访问
                .allowedMethods("GET","POST","PUT","DELETE","HEAD","OPTIONS")//允许哪些方法访问
                .allowCredentials(true)//是否允许携带cookie
                .maxAge(3600)//设置浏览器询问的有效期
                .allowedHeaders("*");//
    }
}

2.6 后端跨域:Nginx解决

参考Nginx 轻松解决跨域问题

2.61 分析前准备:

前端网站地址:http://localhost:8080

服务端网址:http://localhost:59200 

首先保证服务端是没有处理跨域的,其次,先用postman测试服务端接口是正常的

image.png

2.62 通过nginx代理的方式解决

server {
    listen       22222;
    server_name  localhost;
    location  / {
        if ($request_method = 'OPTIONS') {
            add_header Access-Control-Allow-Origin 'http://localhost:8080';
            add_header Access-Control-Allow-Headers '*';
            add_header Access-Control-Allow-Methods '*';
            add_header Access-Control-Allow-Credentials 'true';
            return 204;
        }
        if ($request_method != 'OPTIONS') {
            add_header Access-Control-Allow-Origin 'http://localhost:8080' always;
            add_header Access-Control-Allow-Credentials 'true';
        }
        proxy_pass  http://localhost:59200; 
    }
}