Summary of front-end and back-end separation development cross-domain problems

insert image description here

Development requirements:
In the process of using vue uniapp springboot to develop WeChat applets, the front-end and back-end separation mode is also adopted. The front-end pages and js are deployed in the WeChat applets, and the back-end interfaces are deployed in the Aliyun server. When the request is initiated, it must not comply with the same-origin policy, so it cannot be accessed. It will need to solve the cross-domain problem and realize the front-to-back interaction. This article systematically introduces why cross-domain problems occur and how to deal with them.

1. What is cross-domain access

For cross-domain access, you must first understand a term: same-origin policy

The same-origin policy means that for security reasons on the browser side, the request to the server must meet the following conditions: the same protocol, the same host (ip), and the same port, otherwise access will be prohibited, and access that does not meet the requirements will also be blocked. Known as cross-domain access.

Although cross-domain access is prohibited, the security of the application can be improved to a certain extent, but it also brings some troubles to the development.

Cross-domain means that browsers cannot execute scripts from other websites, which is a security restriction imposed by browsers on JavaScript.

The so-called same origin means: the domain name, protocol, and port are all the same, examples are as follows:

http://www.jumper.com/index.html calls http://www.jumper.com/server.PHP (non-cross domain)

http://www.jumper.com/index.html calls http://www.sun.com/server.php (the main domain name is different: jumper/sun, cross-domain)

http://abc.jumper.com/index.html calls http://def.jumper.com/server.php (different subdomain names: abc/def, cross-domain)

http://www.jumper.com:8080/index.html calls http://www.jumper.com:8081/server.php (different ports: 8080/8081, cross-domain)

http://www.jumper.com/index.html calls https://www.jumper.com/server.php (different protocols: http/https, cross-domain)

Please note: Although localhost and 127.0.0.1 both point to the local machine, they are also cross-domain.

2. Solve cross-domain problems

The following are two ways to solve cross-domain problems: front-end and back-end, and the back-end includes methods. You can use one method, and you don’t need to configure all of them.

1. Vue front-end configuration proxy to solve cross-domain

​ It is relatively simple to solve cross-domain problems in Vue, because the first half of the URL must be the same in each request sent by the browser, such as http://localhost:8080/users and http://localhost:8080/ login, we can extract their same URL and encapsulate it in axios.defaults.baseURL, so that we can abbreviate the request address as "/users" every time we request, which is equivalent to making a simple URL header encapsulation.
request.js

import axios from 'axios'

const request = axios.create({
    
    
	baseURL: '/api',  // 这里是全局统一加上了 '/api' 前缀,也就是说所有接口都会加上'/api'前缀在,其他位置写接口的时候就不要加 '/api'了,否则会出现两个'/api',类似 '/api/api/user'这样的报错,切记!!!
    timeout: 5000
})

// request 拦截器 可以自请求发送前对请求做一些处理
// 比如统一加token,对请求参数统一加密
request.interceptors.request.use(config => {
    
    
    config.headers['Content-Type'] = 'application/json;charset=utf-8';
  
 // config.headers['token'] = user.token;  // 设置请求头
    return config
}, error => {
    
    
    return Promise.reject(error)
});

// response 拦截器 可以在接口响应后统一处理结果
request.interceptors.response.use(
    response => {
    
    
        let res = response.data;
        // 如果是返回的文件
        if (response.config.responseType === 'blob') {
    
    
            return res
        }
        // 兼容服务端返回的字符串数据
        if (typeof res === 'string') {
    
    
            res = res ? JSON.parse(res) : res
        }
        return res;
    },
    error => {
    
    
        console.log('err' + error) // for debug
        return Promise.reject(error)
    }
)


export default request

view.config.js

module.exports = {
    
    
    devServer: {
    
    
        host: 'localhost',
        open: true, // 自动打开浏览器
        // 代理配置表,在这里可以配置特定的请求代理到对应的API接口
        proxy: {
    
    
            '/api': {
    
     // 匹配所有以 '/api'开头的请求路径
                target: 'http://localhost:8080', // 代理目标的基础路径
                // secure: false,   // 如果是https接口,需要配置这个参数
                changeOrigin: true, // 支持跨域
                pathRewrite: {
    
     	    // 重写路径: 去掉路径中开头的'/api'
                    '^/api': ''
                }
            }
        }
    }
}

2. SpringBoot backend configuration solves cross domain

2.1 Cross-domain configuration class CorsConfig(commonly used)

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    
    

    @Override
    public void addCorsMappings(CorsRegistry registry) {
    
    
        registry.addMapping("/**")
                .allowedOriginPatterns("*")
                .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
                .allowCredentials(true)
                .maxAge(3600)
                .allowedHeaders("*");

    }
}

2.2 Add @CrossOriginannotations to Controller

@RestController
@RequestMapping("users/")
public class IndexController {
    
    

    @GetMapping
    @CrossOrigin
    public String users() {
    
    
        return "users";
    }
}

2.3 Add CORS filter CorsFilter(commonly used)

Create a new configuration class CorsFilterConfig, create CorsFiltera filter, and allow cross-domain

@Configuration
public class CorsConfig {
    
    
    // 跨域请求处理
    @Bean
    public CorsFilter corsFilter() {
    
    
        CorsConfiguration config = new CorsConfiguration();
        //允许所有域名进行跨域调用
        config.addAllowedOrigin("*");
        // config.addAllowedOrigin("http://localhost:8080");
            
        //允许所有请求头
        config.addAllowedHeader("*");
        //允许所有方法
        config.addAllowedMethod("*");
        // 为url添加映射路径
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        
        return new CorsFilter(source);
    }
}

2.4 Use Spring Security to solve cross-domain problems

public class SecurityConfig extends WebSecurityConfigurerAdapter{
    
    
@Override
    protected void configure(HttpSecurity http) throws Exception {
    
    
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .and().cors().configurationSource(corsConfigurationSource())
                .and()
                .csrf()
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());//将csrf令牌存储在cookie中 允许cookie前端获取
    }

    CorsConfigurationSource corsConfigurationSource(){
    
    
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedHeaders(Arrays.asList("*"));
        config.setAllowedMethods(Arrays.asList("*"));
        config.setAllowedOrigins(Arrays.asList("*"));
        config.setMaxAge(3600L);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return source;
    }
  }

Guess you like

Origin blog.csdn.net/qq_51808107/article/details/131392845