总结:跨域问题

一、介绍

最近遇到和兄弟部门联调服务时,反馈跨域问题,不知道什么原因,此处特做记录。

二、什么是同源策略?

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,现在所有支持 JavaScript 的浏览器都会使用这个策略。如果缺少了同源策略,浏览器很容易受到 XSS、 CSFR 等攻击。

同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个 ip 地址,也非同源

同源政策的目的:是为了保证用户信息的安全,防止恶意的网站窃取数据

设想这样一种情况

        在京东网站上登陆了账号后,那么又去访问另一个网站,那么你现在的京东账号是登录的状态,并没有退出,然而这个网站是可以看到你在京东网站上登陆的信息和存的一些Cookie,会发生什么?

  • 很显然,如果 Cookie 包含隐私,这些信息就会泄漏。更可怕的是,Cookie 往往用来保存用户的登录状态,如果用户没有退出登录,其他网站就可以冒充用户,为所欲为。因为浏览器同时还规定,提交表单不受同源政策的限制

由此可见,同源政策是必需的,否则 Cookie 可以共享,互联网就毫无安全可言了。

三、什么是跨域

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。

跨域问题来源根据上面说的的同源策略,即只有 协议+域名+端口号相同,则允许相互访问。也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。跨域问题是针对JS和ajax的,html本身没有跨域问题,比如a标签、script标签、甚至form标签可以直接跨域发送数据并接收数据

四、Springboot跨域支持

CORS是跨源资源分享。它是W3C标准,是跨源AJAX请求的根本解决方法。相比JSONP只能发GET请求,CORS允许任何类型的请求。

以下代码是Springboot1.5中的配置,亲测可用。

注意:之前配置一直不生效,后来排查是因为有人配置了一个过滤器导致我下面的配置失效了。

另外,跨域配置后要测试,之前没有正确的测试方式,导致只能硬着头皮上,所以有正确的测试方式很重要,第五点贴了测试方式。

package com.xxx.api.open.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 java.util.ArrayList;
import java.util.List;

/**
 * @Description:
 * @author: chenjiawang
 * @CreateDate: 2019/3/19 15:39
 */
@Configuration
public class CorsConfig {
    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowCredentials(true);  //sessionid 多次访问一致

        // 允许访问的客户端域名
        corsConfiguration.addAllowedOrigin("*"); // 允许任何域名使用
        corsConfiguration.addAllowedHeader("*"); // 允许任何头
        corsConfiguration.addAllowedMethod("*"); // 允许任何方法(post、get等)
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig()); // 对接口配置跨域设置
        return new CorsFilter(source);
    }
}

五、跨域功能测试

有时候,我们后端支持跨域之后,想测试是否生效,可用打开个相同协议的页面(如都是http的),然后F12,在console中输入如下代码,按回车,只要不出现跨域报错就OK了。

var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://10.5.130.12:9507/api/open/alarm/query/queryQkeAlarm');
xhr.setRequestHeader("usertoken","ccfe5");
xhr.send(null);
xhr.onload = function(e) {
var xhr = e.target;
console.log(xhr.responseText);
}

如下说明服务端支持跨域了:

 一般跨域不支持的报错:

以下是因为协议不一样,协议不一样也是跨域。

 以下是因为usertoken这个请求头不被后端允许:

 此种报错,只需要在后端配置允许的请求头即可。解决方式:

六、ngnix跨域支持

没有试验过,记录下 

七、前端支持:避免发生跨域

没有试验过。记录下

使用jsonp,由于jsonp请求是通过script的方式发送的(只有xhr的请求方式才有可能产生跨域问题),所以不会产生跨域问题。Spring MVC实现过程:前台使用ajax的get请求,将dataType设为“jsonp”;服务器创建一个类并继承抽象类AbstractJsonReponseBodyAdvice,最后注解@ControllerAdivece。使用jsonp的弊端,只能使用get方式请求,服务器需要改动代码,发送的不是xhr请求。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值