Vue + Vite + Axios 项目多情况以及摆设前后端跨域

金歌  金牌会员 | 2024-7-15 16:36:58 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 844|帖子 844|积分 2532

最近在前端多情况和摆设服务器之后出现的跨域的问题。
多情况

前端多情况 Vite Axios

1.起首在项目目次下界说多情况的文件。
这里列举开辟情况和发布情况
.env.development 情况
  1. # 开发时加载
  2. // 此处为开发时接口
  3. VITE_API_URL = 'http://localhost:8080/api'
复制代码
.env production 情况
  1. # 发布时加载
  2. // 生产时接口
  3. VITE_API_URL = 'http://xxxxxxxxxxx/api'  线上后端地址
复制代码
2. 在配置的 Axios 识别情况
  1. const myAxios = axios.create({
  2.     //识别环境
  3.     baseURL: import.meta.env.VITE_API_URL as any,
  4.     timeout: 5000,
  5.     headers: { 'Content-Type': 'application/json;charset=UTF-8' },
  6.     // @ts-ignore
  7.     //跨域
  8.     changeOrigin: true
  9. });
复制代码
3. 项目因为使用的是 Vite 打包构建,所以在package文件下的 vite 的 build 命令加上 production
  1. "scripts": {
  2.     "dev": "vite",
  3.     "build": "vite build --mode production",
  4.     "preview": "vite preview"
  5.   },
复制代码

后端多情况 Spring Boot

创建 application-prod.yml 文件,配置信息为线上情况的地点,比如数据库,redis等
  1. #项目名称,此处是spring boot 2.5版本之后的写法,之前的写法不能识别
  2. spring:
  3.   config:
  4.     activate:
  5.       on-profile:
  6.         prod
  7.   application:
  8.     name: guanlixitong
  9.     #数据库配置
  10.   datasource:
  11.     driver-class-name: com.mysql.cj.jdbc.Driver
  12.     username: dazi
  13.     password: 123456
  14.     url: jdbc:mysql://localhost:3306/dazi
  15.   #sesson 失效时间 86400秒
  16.   session:
  17.     timeout: 86400  
  18.     store-type: redis
复制代码
摆设命令
  1. java -jar ./{项目打包之后的 jar 包名称,比如maven打包之后target里的 jar 包} --spring.profiles.active=prod
复制代码
项目启动日志
  1. INFO 14040 --- [           main] c.p.d.UserCenterBackendApplication       : The following 1 profile is active: "prod"
  2. INFO 14040 --- [           main] o.a.catalina.core.AprLifecycleListener   : APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true], UDS [true].   
  3. INFO 14040 --- [           main] o.a.catalina.core.AprLifecycleListener   : APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true]
  4. INFO 14040 --- [           main] o.a.catalina.core.AprLifecycleListener   : OpenSSL successfully initialized [OpenSSL 1.1.1v  1 Aug 2023]
  5. INFO 14040 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
复制代码
可以看到识别到了 prod 情况,后端测试也可以发现可以或许连接上线上数据库了。
(后来线上测试发现 redis 能连上,也能存储数据,但是不能识别登录状态,头疼)

跨域

参考文档:SpringBoot设置Cors跨域的四种方式 - 简书 (jianshu.com)
官方文档:Spring 和 CORS 跨域 - spring 中文网 (springdoc.cn)
1. Nginx 配置
  1. #跨域配置
  2. location ^~ /api/ {
  3.     proxy_pass http://127.0.0.1:8080;   #反向代理配置
  4.     add_header 'Access-Control-Allow-Origin' $http_origin; #预检查请求也需要这行
  5.     add_header 'Access-Control-Allow-Credentials' 'true';
  6.     add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
  7.     add_header Access-Control-Allow-Headers '*';
  8.           if ($request_method = 'OPTIONS'){
  9.         add_header 'Access-Control-Allow-Credentials' 'true';
  10.         add_header 'Access-Control-Allow-Origin' $http_origin;
  11.         add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
  12.         add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
  13.         add_header 'Access-Control-Max-Age' 1728000;
  14.         add_header 'Content-Type' 'text/plain; charset=utf-8';
  15.         add_header 'Content-Length' 0;
  16.         return 204;
  17.     }
  18. }
复制代码
2. 后端 @CrossOrigin 注解
在 controller 文件加上注解
  1. @CrossOringin(origins = {允许跨域的地址}, methods = {可以跨域的请求方式}, allowCredentials = "true")
复制代码
3. 添加 web 全局请求拦截器
  1. //新建config目录,新建在该目录下
  2. @Configuration
  3. public class WebMvcConfg implements WebMvcConfigurer {
  4.     @Override
  5.     public void addCorsMappings(CorsRegistry registry) {
  6.         //设置允许跨域的路径
  7.         registry.addMapping("/**")
  8.                 //设置允许跨域请求的域名
  9.                 //当**Credentials为true时,**Origin不能为星号,需为具体的ip地址【如果接口不带cookie,ip无需设成具体ip】
  10.                 .allowedOrigins("http://localhost:9527", "http://127.0.0.1:9527", "http://127.0.0.1:8082", "http://127.0.0.1:8083")
  11.                 //是否允许证书 不再默认开启
  12.                 .allowCredentials(true)
  13.                 .allowedHeaders(CorsConfiguration.ALL)
  14.                 //设置允许的方法
  15.                 .allowedMethods(CorsConfiguration.ALL)
  16.                 //跨域允许时间
  17.                 .maxAge(3600);
  18.     }
  19. }
  20. 二选一即可
  21. ---------------------------------------------------------------
  22. //Spring 中文网
  23. import org.springframework.context.annotation.Configuration;
  24. import org.springframework.web.servlet.config.annotation.CorsRegistry;
  25. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  26. @Configuration
  27. public class WebMvcConfiguration implements WebMvcConfigurer{
  28.     @Override
  29.     public void addCorsMappings(CorsRegistry registry) {
  30.         registry.addMapping("/**")                  // 允许跨域请求的path,支持路径通配符,如:/api/**
  31.             .allowedOrigins("*")                    // 允许发起请求的源
  32.             .allowedHeaders("*")                    // 允许客户端的提交的 Header,通配符 * 可能有浏览器兼容问题
  33.             .allowedMethods("GET")                  // 允许客户端使用的请求方法
  34.             .allowCredentials(false)                // 不允许携带凭证
  35.             .exposedHeaders("X-Auth-Token, X-Foo")  // 允许额外访问的 Response Header
  36.             .maxAge(3600)                           // 预检缓存一个小时
  37.             ;
  38.     }
  39. }
复制代码
4. CorsFilter
  1. import java.time.Duration;
  2. import org.springframework.boot.web.servlet.FilterRegistrationBean;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.core.Ordered;
  6. import org.springframework.http.HttpHeaders;
  7. import org.springframework.util.StringUtils;
  8. import org.springframework.web.cors.CorsConfiguration;
  9. import org.springframework.web.filter.CorsFilter;
  10. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  11. @Configuration
  12. public class WebMvcConfiguration implements WebMvcConfigurer{
  13.     // 通过 FilterRegistrationBean 注册 CorsFilter
  14.     @Bean
  15.     public FilterRegistrationBean<CorsFilter> corsFilter() {
  16.         
  17.         // 跨域 Filter
  18.         CorsFilter corsFilter = new CorsFilter(request -> {
  19.             
  20.             // 请求源
  21.             String origin = request.getHeader(HttpHeaders.ORIGIN);
  22.             
  23.             if (!StringUtils.hasText(origin)) {
  24.                 return null; // 非跨域请求
  25.             }
  26.             
  27.             // 针对每个请求,编程式设置跨域
  28.             CorsConfiguration config = new CorsConfiguration();
  29.             
  30.             // 允许发起跨域请求的源,直接取 Origin header 值,不论源是哪儿,服务器都接受
  31.             config.addAllowedOrigin(origin);
  32.             
  33.             
  34.             // 允许客户端的请求的所有 Header
  35.             String headers = request.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS);
  36.             if (StringUtils.hasText(headers)) {
  37.                 config.setAllowedHeaders(Stream.of(headers.split(",")).map(String::trim).distinct().toList());
  38.             }
  39.             
  40.             // 允许客户端的所有请求方法
  41.             config.addAllowedMethod(request.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD));
  42.             // 允许读取所有 Header
  43.             // 注意,"*" 通配符,可能在其他低版本浏览中不兼容。
  44.             config.addExposedHeader("*");
  45.             // 缓存30分钟
  46.             config.setMaxAge(Duration.ofMinutes(30));
  47.             // 允许携带凭证
  48.             config.setAllowCredentials(true);
  49.             return config;
  50.         });
  51.         
  52.         FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(corsFilter);
  53.         bean.addUrlPatterns("/*");                  // Filter 拦截路径
  54.         bean.setOrder(Ordered.LOWEST_PRECEDENCE);   // 保证最先执行
  55.         return bean;
  56.     }
  57. }
复制代码
大概出现的问题

  1. //报错信息
  2. The 'Access-Control-Allow-Origin' header contains multiple values'*, *', but only one is allowed.
复制代码
域名冲突,大概是上述配置跨域重复,比如 Nginx 配置和后端配置,只需要删除某一个即可,比如 Nginx 配置中的关于请求头,请求方法等,具体看现实测试情况。

上述配置 末了选择了 Nginx 配置,注解在开辟时有用,但是一摆设线上之后就不见效,缘故原由不知。其他的或多或少会报错,比如 Get 请求不跨域,Post 请求就跨域。。。
知识尚浅,有错误烦请指出。




免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

金歌

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表