前后端处理跨域

跨域

首先我们先了解一下跨域

1、为什么会出现跨域:出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。
2、什么是跨域:当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

怎么解决跨域

前端代理解决跨域

vue代理服务器proxy跨域:通过请求本地的服务器,然后本地的服务器再去请求远程的服务器(后端部署接口的服务器),最后本地服务器再将请求回来的数据返回给浏览器(本地服务器和浏览器之前不存在跨域)

// vue.config.js
  devServer: {
    port: port,
    // open: true,
    overlay: {
      warnings: false,
      errors: true
    },
    proxy: {
      // detail: https://cli.vuejs.org/config/#devserver-proxy
      "/dev-api": {
        target: "http://localhost:4000/frame_base",
        changeOrigin: true,
        logLevel: "debug", // 查看真实请求地址
        pathRewrite: {
          ["^" + "/dev-api"]: ""
        }
      }
    },
    after: require("./mock/mock-server.js")
  }

 

后端解决跨域

需要前端开启cookie携带

const defaultConfig = {
  baseURL: BASE_URL,
  // 请求超时时间
  timeout,
  headers: {
    Accept: "application/json, text/plain, */*",
    "Content-Type": "application/json",
    "X-Requested-With": "XMLHttpRequest"
  },
  // 允许携带cookie
  withCredentials: true,
  // 数组格式参数序列化(https://github.com/axios/axios/issues/5142)
  paramsSerializer: params => stringify(params, { indices: false })
};

 

Spring-CORS规则基础配置

想在SpringSpring Bootweb环境下实现跨域资源共享,主要有三种实现方式:

 

1、使用HttpServletResponse设置响应头(局部跨域配置)。
2、@CrossOrigin注解,这个注解是作用于Controller类或者请求方法上的,(局部跨域配置)。
3、实现WebMvcConfigurer接口addCorsMappings方法,(全局跨域配置)。
4、注入CorsFilter过滤器,实现全局配置的跨域资源共享。(全局跨域配置)。

1、使用HttpServletResponse设置响应头

@RequestMapping("/cors")
@ResponseBody
public String cors(HttpServletResponse response){
    //使用HttpServletResponse定义HTTP请求头,最原始的方法也是最通用的方法
    response.addHeader("Access-Control-Allow-Origin", "http://localhost:8080");
    return "cors";
} 

 

2、在controller类或者下面的方法上加上@CrossOrigin注解

package com.icreate.controller;

import com.qiehua.CXK;
import java.util.List;

@RestController
@CrossOrigin
public class VisitController {
   
    @PostMapping("/cxk/jntm")
    public List<CXK> register(@RequestBody CXK  cxk){
    return null;
}


package com.icreate.controller;

import com.qiehua.CXK;
import java.util.List;

@RestController
public class VisitController {

    @CrossOrigin
    @PostMapping("/cxk/jntm")
    public List<CXK> register(@RequestBody CXK  cxk){
    return null;
}

3、添加配置类

package com.qiehua.config;

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

@SpringBootConfiguration
public class MyWebConfigurer implements WebMvcConfigurer {
    /**
     * 所有请求都允许跨域,使用这种配置就不需要在interceptor中配置header了
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
      registry.addMapping("/**")
        .allowedOrigins("http://localhost:9527", "http://127.0.0.1:4000")
        .allowedHeaders("*")
        .allowedMethods("*")
        .exposedHeaders("Content-Type, Cookie, Authorization, Set-Cookie")
        .allowCredentials(true).maxAge(3600);
    }
}


4、添加过滤器

    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.addAllowedOrigin("http://localhost:9527");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.addAllowedHeader("*");
        // 允许响应头显示Authorization属性
        corsConfiguration.addExposedHeader("Content-Type, Cookie, Authorization, Set-Cookie");
        UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(urlBasedCorsConfigurationSource);
    }

Spring Security 中的配置CORS

当我们的应用使用了Spring Security 之后,我们会发现上面的配置方法全部失效。此时需要在spring securityWebSecurityConfigurerAdapter中的configure(HttpSecurity http)配置方法,加上http.cors()配置,第二小节中的配置才会生效。

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and()
        ...
    }
}

另外Spring Security为我们提供了一种新的CORS规则的配置方法:CorsConfigurationSource 。使用这种方法实现的效果等同于注入一个CorsFilter过滤器。

    // Spring Security 解决跨域问:
    // 1、既要 上面常用四种之一 
    // 2、又要 http.cors().configurationSource(corsConfigurationSource())
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowedOrigins(Arrays.asList("http://localhost:9527", "http://127.0.0.1:4000"));
        corsConfiguration.setAllowedHeaders(Arrays.asList("*"));
        corsConfiguration.setAllowedMethods(Arrays.asList("*"));
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.setMaxAge(3600L);
        // 允许响应头显示Authorization属性
        corsConfiguration.addExposedHeader("Content-Type, Cookie, Authorization, Set-Cookie");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfiguration);
        return source;
    };

4、方法二

    // Spring Security 解决跨域问题: 1、http.cors(); 2、corsFilter()
    private CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.addExposedHeader(SessionConst.HEAD_AUTHORIZATION);
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.setMaxAge(3600L);
        UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
        return urlBasedCorsConfigurationSource;
    };

    // 如果不是 Security 框架, corsFilter() 即可配置跨域
    @Bean
    public CorsFilter corsFilter() {
        return new CorsFilter(corsConfigurationSource());
    }