跨域问题及解决方案

跨域问题是指在前端Web开发中,不同源的网页之间无法相互访问或通信的问题。产生跨域问题的原因是由于浏览器的同源策略(Same Origin Policy)所导致的。

同源策略是浏览器的一种安全机制,限制了来自不同源(域名、端口、协议)的文档或脚本之间的交互,如 XMLHttpRequest 或 Fetch 请求、跨窗口和跨框架访问文档或脚本等。同源策略的目的是保护用户的隐私和安全,防止恶意代码窃取用户的信息或篡改网页内容。

举个例子,假设有两个网站 A 和 B,它们的 URL 如下:

A网站:https://www.a.com
B网站:https://www.b.com
由于 A 和 B 的协议(http/https)、主机名(www.a.com 和 www.b.com)和端口号(默认为80)都不相同,因此它们被认为是不同的源。如果在A网站中使用 JavaScript 代码尝试获取B网站的数据,就会受到同源策略的限制,无法成功获取数据。

要解决跨域问题,一般有以下几种方式:

JSONP(JSON with Padding)跨域请求:通过在页面上添加一个 标签,并指定其 src 属性为跨域请求的 URL,服务器返回的数据会被当做 JavaScript 代码执行,从而实现跨域数据的获取。不过 JSONP 只支持 GET 请求,且无法处理 POST 请求等场景。
CORS(Cross-Origin Resource Sharing)跨域请求:通过在服务端设置响应头部的 Access-Control-Allow-* 字段,授权指定源可以访问资源,从而实现跨域数据的获取。CORS 请求支持 GET 和 POST 等任意请求方式。
代理跨域请求:通过在自己的服务器上建立代理服务器,将前端请求发送给代理服务器,再由代理服务器向目标服务器发送请求,并返回目标服务器的响应。通常用于请求第三方 API 数据等场景。
解决方案:
前端与后端都会有解决方案
但前端往往不能根本解决问题!
因此如何你的后端同事让作为前端工程师的你来解决问题,请一定来打他!

后端较为主流的解决方案
就在在config中进行配置

package com.fanchen.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;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 跨域请求配置
 * 解决跨域问题的配置
 *
 */
@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Bean
    public CorsFilter corsFilter(){
        // 1. 添加cors配置信息
        CorsConfiguration config = new CorsConfiguration();
        // Response Headers里面的Access-Control-Allow-Origin: http://localhost:8080
        config.addAllowedOrigin("http://localhost:8081");
        // 其实不建议使用*,允许所有跨域
        //config.addAllowedOrigin("*");
        // 设置是否发送cookie信息,在前端也可以设置axios.defaults.withCredentials = true;表示发送Cookie,
        // 跨域请求要想带上cookie,必须要请求属性withCredentials=true,这是浏览器的同源策略导致的问题:不允许JS访问跨域的Cookie
        /**
         * withCredentials前后端都要设置,后端是setAllowCredentials来设置
         * 如果后端设置为false而前端设置为true,前端带cookie就会报错
         * 如果后端为true,前端为false,那么后端拿不到前端的cookie,cookie数组为null
         * 前后端都设置withCredentials为true,表示允许前端传递cookie到后端。
         * 前后端都为false,前端不会传递cookie到服务端,后端也不接受cookie
         */
        // Response Headers里面的Access-Control-Allow-Credentials: true
        config.setAllowCredentials(false);
        // 设置允许请求的方式,比如get、post、put、delete,*表示全部
        // Response Headers里面的Access-Control-Allow-Methods属性
        config.addAllowedMethod("*");
        // 设置允许的header
        // Response Headers里面的Access-Control-Allow-Headers属性,这里是Access-Control-Allow-Headers: content-type, headeruserid, headerusertoken
        config.addAllowedHeader("*");
        // Response Headers里面的Access-Control-Max-Age:3600
        // 表示下回同一个接口post请求,在3600s之内不会发送options请求,不管post请求成功还是失败,3600s之内不会再发送options请求
        // 如果不设置这个,那么每次post请求之前必定有options请求
        // 当前跨域请求最大有效时长。这里默认1天
        long maxAge = 24 * 60 * 60;
        config.setMaxAge(maxAge);
        config.addExposedHeader("Authorization");
        // 2. 为url添加映射路径
        UrlBasedCorsConfigurationSource corsSource = new UrlBasedCorsConfigurationSource();
        // /**表示该config适用于所有路由
        corsSource.registerCorsConfiguration("/**", config);
        // 3. 返回重新定义好的corsSource
        return new CorsFilter(corsSource);
    }
}

你可能感兴趣的:(javascript,java,前端)