自由的羽毛 发表于 2024-6-11 11:40:29

四种跨域解决方案

1.引出跨域

1.基本介绍

https://img-blog.csdnimg.cn/img_convert/84b232d1abc0e69b139d65cdce9eed7e.png
2.具体演示

1.启动之前学习过的springboot-furn项目

https://img-blog.csdnimg.cn/img_convert/a6a2dd825a476770cd43630ce5de318b.png
2.欣赏器直接访问 localhost:8081/furns 可以体现信息

https://img-blog.csdnimg.cn/img_convert/5244d13d861abed6141353cde6931321.png
3.启动前端项目,取消请求拦截器,这样设置,就会出现跨域

https://img-blog.csdnimg.cn/img_convert/c1c601fa5c4fbe85d401ddb53792e5e5.png
https://img-blog.csdnimg.cn/img_convert/cb69b9637977e3f5b18fa5abb723ffec.png
4.跨域原因



[*]当前端项目请求到后端,会返回跨域请求拦截
[*]原因是欣赏器默认实行同源策略,会克制读取localhost:8081的资源
2.跨域题目介绍

1.是什么?

https://img-blog.csdnimg.cn/img_convert/78d7182ade31fd96535de06156253c2b.png
2.同源策略

https://img-blog.csdnimg.cn/img_convert/bf9755e191291c40c7b88dc7c7717483.png
3.跨域流程

1.简单请求和非简单请求

1.简单请求

https://img-blog.csdnimg.cn/img_convert/36576fcc2fc2448474cc6e237567f12f.png
2.非简单请求(不满足简单请求的就黑白简单请求)

2.简单请求-跨域流程

https://img-blog.csdnimg.cn/img_convert/c323c2a7a9f0ef805ecb16073d0a6c2d.png
3.非简单请求-跨域流程

https://img-blog.csdnimg.cn/img_convert/75eeac299f6a9aa6f76ad14a9af30f42.png
4.非简单请求演示

1.这里的添加就黑白简单请求

https://img-blog.csdnimg.cn/img_convert/9058f6c528d41341f723860a877fdcb9.png
2.测试请求,预检请求失败,不会发送真实请求

https://img-blog.csdnimg.cn/img_convert/fc1db0ee66ab5d3b618d8f79cc418118.png
4.跨域解决方案

1.Nginx反向代理

https://img-blog.csdnimg.cn/img_convert/27411e5b6dad9342e1e59badad8a3b88.png
https://img-blog.csdnimg.cn/img_convert/fcef5b87a65b6e95036dafe25e564165.png
2.设置服务器允许跨域

https://img-blog.csdnimg.cn/img_convert/e83a95b1f59ffbade395ed45a0128ca5.png
https://img-blog.csdnimg.cn/img_convert/3cf4c5468b4e7b9081b1c31d2261ad65.png
https://img-blog.csdnimg.cn/img_convert/e40f0d75ff387d898d659c422cefce98.png
3.前端启用代理,设置同源

https://img-blog.csdnimg.cn/img_convert/464d8b27c037c339e052b29f7b9ff5d8.png
5.跨域实操

1.全局CORS设置

1.后端编写设置类 CorsConfig.java

package com.sun.furn.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/**
* Description: 全局跨域配置
*
* @Author sun
* @Create 2024/5/15 10:42
* @Version 1.0
*/
// 全局跨域配置
@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter() {
      // 创建跨域配置,添加 CORS 配置信息
      final CorsConfiguration corsConfiguration = new CorsConfiguration();
      // 跨域请求默认不包含 cookie,设置为 true 可以包含 cookie
      corsConfiguration.setAllowCredentials(true);
      // 支持哪些来源的请求跨域, 支持
      corsConfiguration.addAllowedOriginPattern("*");
      // corsConfiguration.addAllowedOrigin("*");
      // 支持哪些头信息
      corsConfiguration.addAllowedHeader("*");
      // 支持哪些方法跨域
      corsConfiguration.addAllowedMethod("*");
      // 添加映射路径
      final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource
                = new UrlBasedCorsConfigurationSource();
      // /** 是一个正则表达式,表示所有请求 the mapping pattern
      // corsConfiguration 跨域配置
      urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
      // 返回新的 CorsFilter.
      return new CorsFilter(urlBasedCorsConfigurationSource);
    }
}

2.成功解决跨域

https://img-blog.csdnimg.cn/img_convert/52380a967e6233642237b210e59dfc64.png
3.查看响应头,后端允许跨域

https://img-blog.csdnimg.cn/img_convert/c964d4b56057bee8d5e7aeccb4c3b0d6.png
2.添加CORS设置类(只是跟上面的形式不同)

1.后端编写设置类 WebMvcConfig.java

package com.sun.furn.config;

/**
* Description: 全局跨域配置
*
* @Author sun
* @Create 2024/5/15 11:49
* @Version 1.0
*/

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

@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
      registry.addMapping("/**") // 允许跨域访问的路径
                .allowedOriginPatterns("*") // 允许跨域访问的源
                .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") // 允许请求方法
                .maxAge(3600) // 预检间隔时间
                .allowCredentials(true); // 是否发送cookie
    }
}
2.成功解决跨域

https://img-blog.csdnimg.cn/img_convert/5e4c8230aa582686ab010eadd8305f09.png
3.使用Filter方法实现

1.后端创建一个过滤器 CorsFilter.java

package com.sun.furn.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
* Description: 使用过滤器解决跨域问题
*
* @Author sun
* @Create 2024/5/15 13:25
* @Version 1.0
*/
@WebFilter(urlPatterns = "*")
public class CorsFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
      HttpServletRequest httpRequest = (HttpServletRequest)request;
      HttpServletResponse httpResponse = (HttpServletResponse) response;
      httpResponse.setCharacterEncoding("UTF-8");
      httpResponse.setContentType("application/json; charset=utf-8");
      httpResponse.setHeader("Access-Control-Allow-Origin", "*");
      httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
      httpResponse.setHeader("Access-Control-Allow-Methods", "*");
      httpResponse.setHeader("Access-Control-Allow-Headers", "Content-Type,Authorization");
      httpResponse.setHeader("Access-Control-Expose-Headers", "*");
      filterChain.doFilter(httpRequest, httpResponse);
    }
    @Override
    public void destroy() {
    }
}
2.启动类添加 @ServletComponentScan 注解,扫描servlet组件

https://img-blog.csdnimg.cn/img_convert/848b376fc8a258d6db53a8820f2472b0.png
3.成功解决跨域

https://img-blog.csdnimg.cn/img_convert/d77c0e9e5f855faa0eb12d56a75ba916.png
4.Vue项目启用代理

1.在vue.config.js中添加代理

// 跨域配置
module.exports = {
devServer: {
    port: 9999,// 本地服务端口
    proxy: { //设置代理,必须填
      '/api': { //设置拦截器 拦截器格式 斜杠+拦截器名字,名字可以自己定
      target: 'http://localhost:8081', //代理的目标地址
      changeOrigin: true, //是否设置同源,输入是的
      pathRewrite: { //路径重写
          '/api': '' //选择忽略拦截器里面的单词
      }
      }
    }
}
}
2.修改请求以/api的方式发送请求

https://img-blog.csdnimg.cn/img_convert/00e9757077f1d949712737834ffedfc3.png
3.成功解决跨域



[*]这种方式就相当于是本机对携带/api的请求举行代理,请求携带 Sec-Fetch-Site:same-origin 表示允许跨域
https://img-blog.csdnimg.cn/img_convert/702be34d493f858e158e674971648561.png
6.跨域小结

1.同源策略限定内容

https://img-blog.csdnimg.cn/img_convert/f8902bd3d714f98d6335a04f4c91c37b.png
2.请求跨域了,到底发出去没有

https://img-blog.csdnimg.cn/img_convert/2d02b285144dd2f4c9ff4ca1fe61efb4.png
3.form表单可以跨域提交的,但是Ajax请求不可以跨域请求

https://img-blog.csdnimg.cn/img_convert/55ab935b62bdeba452ac9a1e6a765f91.png
4.推荐跨域处理方式



[*]服务器端解决跨域
[*]Nginx动静分离 + 反向代理

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 四种跨域解决方案