为什么会跨域,要先了解浏览器的同源策略SOP(Same Orign Policy)  https://segmentfault.com/a/1190000015597029

同源:

  如果两个页面的协议,端口(如果有指定)和主机都相同,则两个页面具有相同的源。

  协议/主机/端口

跨源网络访问

  同源策略控制了不同源之间的交互,例如在使用XMLHttpRequest时会受到同源策略的约束。即同源策略限制了从一个源加载的文档或者脚本如何与另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。

  如果没有同源策略限制的接口请求则容易被CSRF攻击,下面是CSRF攻击的原理:

  

解决方案:

CORS

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

CORS需要浏览器和服务器同时支持。

  1. 所有浏览器都支持该功能,IE浏览器不能低于IE10。
    整个CORS通信过程,都是浏览器自动完成,不需要用户参与。 对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
  2. 实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

即CORS与普通请求代码一样。

CORS与JSONP相比

  1. JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。
  2. 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。
  3. JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS。

  

  CORS全称为Cross Origin Resource Sharing(跨域资源共享), 每一个页面需要返回一个名为Access-Control-Allow-Origin的http头来允许外域的站点访问,你可以仅仅暴露有限的资源和有限的外域站点访问。

  我们可以理解为:如果一个请求需要允许跨域访问,则需要在http头中设置Access-Control-Allow-Origin来决定需要允许哪些站点来访问,如要允许www.baidu.com这个站点的请求跨域,则可以设置:

Access-Control-Allow-Origin:http://www.baidu.com

  

  CROS跨域常用header
  Access-Control-Allow-Origin: 允许哪些ip或域名可以跨域访问
  Access-Control-Max-Age: 表示在多少秒之内不需要重复校验该请求的跨域访问权限
  Access-Control-Allow-Methods: 表示允许跨域请求的HTTP方法,如:GET、POST、PUT、DELETE
  Access-Control-Allow-Headers: 表示访问请求中允许携带哪些Header信息,如:Accept、Accept-Language、Content-  Language、Content-Type

spring中解决跨域问题的方案:

1、@CrossOrigin注解

此注解既可用于方法也可用于类

示例如下:

@CrossOrigin(origins = "http://www.zhihu.com")
@RequestMapping(value = "/allProductions", method = RequestMethod.GET)
public Result getAllOldProductions() { }

@CrossOrigin 注解既可注解在方法上,也可注解在类上。

2、XML全局配置

所有跨域请求都可以访问

<mvc:cors>
<mvc:mapping path="/**" />
</mvc:cors>

更加细粒度的配置:

<mvc:cors>

    <mvc:mapping path="/api/**"
allowed-origins="https://domain1.com, https://domain2.com"
allowed-methods="GET, PUT"
allowed-headers="header1, header2, header3"
exposed-headers="header1, header2" allow-credentials="true"
max-age="123" /> <mvc:mapping path="/resources/**"
allowed-origins="https://domain1.com" /> </mvc:cors>

Springboot解决跨域问题配置 

1、使用@CrossOrigin注解,同上

2、使用CorsFilter进行全局跨域配置

@Configuration
public class GlobalCorsConfig { @Bean
public CorsFilter corsFilter() {
CorsConfiguration corsConfig = new CorsConfiguration();
// 开放哪些ip、端口、域名的访问权限,星号表示开放所有域
corsConfig.addAllowedOrigin("*");
// 允许发送cookie信息
corsConfig.setAllowCredentials(true);
// 允许get,post方法
corsConfig.addAllowedMethod(HttpMethod.POST);
corsConfig.addAllowedMethod(HttpMethod.GET);
// 允许HTTP请求头中携带哪些header信息
corsConfig.addAllowedHeader("*");
// 暴漏哪些头部信息(因为跨域访问默认不能获取全部头部信息)
corsConfig.addExposedHeader("Content-Type"); // 添加映射路径,“/**”表示对所有的路径实行全局跨域访问权限的设置
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfig); return new CorsFilter(source);
}
}

3、重写WebMvcConfigurer的addCorsMappings方法(全局跨域配置)

@Bean
public WebMvcConfigurer crosConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") //对哪些映射路径应用跨域配置
.allowedOrigins("*") // 允许哪些域名访问
.allowCredentials(true)
.allowedMethods("GET", "POST")
.allowedHeaders("*")
.exposedHeaders("Content-Type");
}
};
}

或者:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration
public class GlobalCorsConfig implements WebMvcConfigurer{ @Override
  public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("HEAD", "GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowCredentials(true)
.maxAge(3600)
.allowedHeaders("*");
}
}

4、过滤器实现

@Component
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
res.addHeader("Access-Control-Allow-Credentials", "true");
res.addHeader("Access-Control-Allow-Origin", "*");
res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
res.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN");
if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) {
response.getWriter().println("ok");
return;
}
chain.doFilter(request, response);
} @Override
public void init(FilterConfig filterConfig) throws ServletException { } @Override
public void destroy() { }
}

Cross-Origin跨域问题的更多相关文章

  1. Ajax--同源策略,jsonp跨域传输原理(callback),

    什么是同源策略? 阮一峰的博客 同源策略 同源策略的解决方法: 跨域传输 img 标签的src是可以引入其他域名下的图片 script标签的src属性同理 ,也可以引入其他域名下的js文件,并执行 1 ...

  2. 使用pdf.js实现前端页面预览pdf文档,解决了跨域请求

    pdf.js主要包含两个库文件,一个pdf.js和一个pdf.worker.js,,一个负责API解析,一个负责核心解析 官网地址:http://mozilla.github.io/pdf.js/ 下 ...

  3. Ajax本地跨域问题 Cross origin requests are only supported for HTTP

    问题:打开本地html文件时,报错如下 Cross origin requests are only supported for protocol schemes: http, data,chrome ...

  4. CORS (Cross Origin Resources Share) 跨域

    CORS 跨域 1 什么是跨域问题 基于安全考虑,浏览器会限制使用脚本发起任何跨域请求. 所谓的跨域请求,就是与当前页面的 http/ip/port 不一样的请求. 但在实际运用中,跨域获取数据的需求 ...

  5. 跨域问题:Cross origin requests are only supported for protocol schemes: http...

    跨域:Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extensi ...

  6. spring 跨域 CORS (Cross Origin Resources Share) 跨域

    Spring提供了三种方式跨域 1.CorsFilter 过滤器 2.<mvc:cors> Bean(全局,推荐使用) 3.@CrossOrigin注解 以上三种方式本质都是用来配置Cor ...

  7. 关于ajax跨域请求(cross Domain)

    Cross Domain AJAX主要就是A.com网站的页面发出一个XMLHttpRequest,这个Request的url是B.com,这样的请求是被禁止的,浏览器处于安全考虑不允许进行跨域访问, ...

  8. iframe跨域问题:Uncaught DOMException: Blocked a frame with origin解决方法

    在前后端分离的情况下,前台页面将后台页面加载在预留的iframe中:但是遇到了iframe和主窗口双滚动条的情况,由此引申出来了问题: 只保留单个滚动条,那么就要让iframe的高度自适应,而从主页面 ...

  9. 跨域拦截Access-Control-Allow-Origin设置多个origin

    在Extjs和java项目碰到了需要同时处理跨域,外部要访问后台接口的问题 原来的代码是这样,只能设置一个extjs前台需要过滤的跨域请求 package com.xgt.config; import ...

  10. 跨域问题 Blocked a frame with origin "http://......" from accessing a cross-origin frame.

    为了轻松偷懒,不想从目的项目中开发目标项目中的页面,但目的项目中需要获取老项目中的页面,这里用了iframe跨域链接页面出现了问题 Blocked a frame with origin " ...

随机推荐

  1. 命令制作Mac系统U盘启动

    命令 sudo /Applications/Install\ macOS\ Mojave.app/Contents/Resources/createinstallmedia --volume /Vol ...

  2. MySQL视图,函数,触发器,存储过程

    1. 视图 视图是一个虚拟表,它的本质是根据SQL语句获取动态的数据集,并为其命名,用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的临时表摘出来, ...

  3. BAT批处理中的字符串处理详解(字符串截取)

    BAT批处理中的字符串处理详解(字符串截取)   BAT批处理中的字符串处理详解(字符串截取 批处理有着具有非常强大的字符串处理能力,其功能绝不低于C语言里面的字符串函数集.批处理中可实现的字符串处理 ...

  4. Linux 包管理

    1 文集 <Linux 包管理基础:apt.yum.dnf 和 pkg>,由Snapcrafter翻译,英文原创(作者Brennen)地址在这里. 这是一篇不错的概括性的文章,系统介绍了D ...

  5. ionic2中使用极光IM的WebSDK实现即时聊天

    本文主要介绍如何在ionic项目中集成极光IM的WebSDK,详细文档可参考官方介绍. 一.准备 1. 注册激光账号,进入开发者服务页面创建应用. 2. 创建应用后须完成对应平台的推送设置,进行应用或 ...

  6. Java设计模式之建造者模式(生成器模式)

    建造者模式: 也叫生成器模式.用来隐藏复合对象的创建过程,他把复合对象的创建过程加以抽象,通过子类继承和重载的方式,动态地创建具有复合属性的对象. 总结一句就是封装一个对象的构造过程,并允许按步骤构造 ...

  7. debian安装redis

    添加rc.local文件cat </etc/rc.local#!/bin/sh -eexit 0EOF cd /opt wget http://download.redis.io/release ...

  8. WebSocket的Tomcat实现

    一.WebSocket简单介绍 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通 ...

  9. SpringCloud使用Nacos服务发现实现远程调用

    本文使用SpringCloud结合Nacos服务发现,Feign远程调用做一个简单的Demo. 1 Nacos 关于Nacos之前写了两篇文章关于SpringBoot对它的使用,感兴趣可以查看一下. ...

  10. Linux 下执行本目录的可执行文件(命令)为什么需要在文件名前加“./”

    一.PATH 是环境变量,里面保存了执行文件路径(通常会包含多个路径,各路径之间以冒号":"进行间隔).当执行一个可执行文件(命令)时,Linux 会优先到 PATH 环境变量中保 ...