SpringMvc 跨域处理

导读

  由于浏览器对于JavaScript同源策略的限制,导致A网站(Ajax请求)不能通过JS访问B网站的数据,于是跨域问题就出现了。

跨域指的是域名、端口、协议的组合不同就是跨域。

  1. http://www.chenyanbin.com/
  2. https://www.chenyanbin.com/
  3. http://www.chenyanbin.cn
  4. http://www.chenyanbin.com:8080/

为什么要有同源策略?

  举个例子:比如一个黑客程序,他利用IFrame把真正的银行登录页面嵌套到他的页面上,当你使用真实的用户名,密码登录时,他的页面就可以通过JavaScript读取到你的表单中input中的内容,这样用户名、密码就轻松到手啦。

如何解决跨域?

  解决跨域的方式有多种,比如基于JavaScript的解决方式、基于Jquery的JSONP、以及基于CORS的方式。

  JSONP和CORS的区别之一:JSONP只能解决get方式提交CORS不仅支持GET方式,同时支持POST提交方式。

  我们重点讲解CORS跨域方式。

什么是CORS?

  CORS是一个W3C标准,全称是“跨域资源共享”(Cross-origin resource sharing)。

  它允许浏览器向跨资源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

  CORS需要浏览器服务器同时支持。目前,所有浏览器都支持该功能,浏览器不能低于IE10

  CORS原理:只需要向响应头header中注入:Access-Control-Allow-Origin,这样浏览器检测header中的:Access-Control-Allow-Origin,则就可以跨域操作了。

CORS请求分类标准

  浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple-request)。

简单请求

  凡是不同时满足上面两个条件,就属于非简单请求

  浏览器对这两种请求的处理,是不一样的。

  对于一个简单请求,浏览器直接发出CORS请求,具体来说,就是在头信息之中,加上一个Origin字段。

请求信息

响应信息

字段说明

  1. Access-Control-Allow-Origin:该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接收任意域名的请求。
  2. Access-Control-Allow-Credentials:该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中,设为True,即表示服务器明确许可,Cookie可以包含在请求中,一起发送给服务器。这个值也只能设为True,如果服务器不要浏览器发送Cookie,删除即可。

非简单请求

  非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或者DELETE,或者Content-Type字段的类型是:application/json。

  非简单请求CORS请求,会在正式通信,增加一次HTTP查询请求,称为“预检”请求(preflight)。

  浏览器先咨问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

请求信息

  Http请求的方式是put,并发送一个自定义头信息:X-Custom-Header。

  浏览器发现,这是一个非简单请求,就自动发出一个“预检”请求,要求服务器确认可以这样请求。下面是这个“预检”请求的HTTP头信息。

“预检”请求用的请求方法是OPTIONS,表示这个请求是用来咨问的。头信息里面,关键字端是Origin,表示请求来自那个源。

除了Origin字段,“预检”请求的头信息包括两个特殊字段。

  1. Access-Control-Request-Method:该字段是必须的,用来列出浏览器的CORS请求会用到哪些HTTP方法,上例是PUT。
  2. Access-Control-Request-Header:该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段,上例是X-Custom-Header。

一旦服务器通过了“预检”请求,以后每次浏览器正常的CORS请求,就都跟简单请求一样了。会有一个Origin头信息字段。服务器的回应,也都会有一个Access-Control-Allow-Origin头信息字段。

CORS实现

使用SpringMvc的拦截器实现

具体的【SpringMvc 拦截器】参考

跨域不提交Cookie

package com.cyb.ssm.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;

public class MyHandlerIntercepter implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        System.out.println("Origin:"+request.getHeader("Origin"));
        if (request.getHeader("Origin") != null) {
            response.setContentType("text/html;charset=UTF-8");
            // 允许哪一个URL
            response.setHeader("Access-Control-Allow-Origin", "*");
            // 允许那种请求方法
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
            response.setHeader("XDomainRequestAllowed", "1");
            System.out.println("正在跨域");
        }
        return true; //True:允许访问;False:不允许访问
    }
}

拦截器的配置,请参考【SpringMvc 拦截器

跨域提交Cookie

  Access-Control-Allow-CredentialsTrue的时候,Access-Control-Allow-Origin一定不能设置为“*”,否则报错

  如果有多个拦截器,一定要把处理跨域请求拦截器放首位

AJAX

JAVA代码

public class AllowOriginInterceptor implements HandlerInterceptor {
 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
       if (request.getHeader("Origin") != null) {
           response.setContentType("text/html;charset=UTF-8");
           // 允许哪一个URL 访问 request.getHeader("Origin") 根据请求来的url动态允许
          response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
           // 允许那种请求方法
          response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE,HEAD");
           response.setHeader("Access-Control-Max-Age", "0");
           // 允许请求头里的参数列表
           response.setHeader("Access-Control-Allow-Headers",
                  "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token");
           // 允许对方带cookie访问
     response.setHeader("Access-Control-Allow-Credentials", "true");
          response.setHeader("XDomainRequestAllowed", "1");
           System.out.println("正在跨域");
       }
       return true;
    }
}

原文地址:https://www.cnblogs.com/chenyanbin/p/12045237.html

时间: 2024-10-27 21:31:27

SpringMvc 跨域处理的相关文章

SpringMvc跨域支持

SpringMvc跨域支持 在controller层加上注解@CrossOrigin可以实现跨域 该注解有两个参数 1,origins  : 允许可访问的域列表 2,maxAge:飞行前响应的缓存持续时间的最大年龄(以秒为单位). 原文地址:https://www.cnblogs.com/cailijuan/p/8656484.html

springmvc跨域(转)

跨域资源共享 CORS 详解 原文链接:http://www.ruanyifeng.com/blog/2016/04/cors.html 作者: 阮一峰 日期: 2016年4月12日 CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制. 本文详细介绍CORS的内部机制. (图片说明:摄于阿联酋艾因(Al Ain)的绿洲公园)

(H5)FormData+AJAX+SpringMVC跨域异步上传文件

最近都没时间整理资料了,一入职就要弄懂业务,整天被业务弄得血崩. 总结下今天弄了一个早上的跨域异步上传文件.主要用到技术有HTML5的FormData,AJAX,Spring MVC. 首先看下上传页面: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script type="text/javascript" src="js/plugins/

springmvc跨域+token验证

  1)app后台跨域设置      2)拦截器中设置http报文header中token      3)token的生成实现 ==================================================================================================== 1,app后台跨域的设置 1.1   springmvc4 有直接在请求映射中对跨域的处理,只需加一个@CrossOrign() @CrossOrigin(origins

Springmvc跨域请求

@CrossOrigin(origins = "*", maxAge = 3600) public abstract class BaseController { @InitBinder public void initBinder(ServletRequestDataBinder binder) { // 自动转换日期类型的字段格式 binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateF

跨域解决方案与提交订单

跨域解决方案与提交订单 课程目标  目标 1:掌握跨域请求 CORS 解决方案目标 2:完成结算页收货人地址选择功能目标 3:完成结算页支付方式选择目标 4:完成结算页商品清单功能目标 5:完成保存订单功能 1.商品详细页跨域请求  1.1 需求分析  从商品详细页点击“加入购物车”按钮,将当前商品加入购物车,并跳转到购物车页面. 1.2 JS 跨域请求  这里说的 js 跨域是指通过 js 在不同的域之间进行数据传输或通信,比如用 ajax 向一个不同的域请求数据,或者通过 js 获取页面中不

SpringMvc+AngularJS通过CORS实现跨域方案

什么是跨域请求问题? 这个问题的起因在于现代浏览器默认都会基于安全原因而阻止跨域的ajax请求,这是现代浏览器中必备的功能,但是往往给开发带来不便. 但跨域的需求却一直都在,为了跨域,勤劳勇敢的程序猿们想出了许许多多的方法,例如,jsonP.代理文件等等.但这些做法增加了许多不必要的维护成本,而且应用场景也有许多限制,例如jsonP并非XHR,所以jsonP只能使用GET传递参数. 在移动应用风生水起的如今,托HTML5的福,Mobile Web,甚至Hybird App也逐渐火起来,在本地文件

SpringMVC中利用@CrossOrigin注解解决ajax跨域请求的问题

1. 什么是跨域 跨域,即跨站HTTP请求(Cross-site HTTP request),指发起请求的资源所在域不同于请求指向资源所在域的HTTP请求. 2. 跨域的应用情景 当使用前后端分离,后端主导的开发方式进行前后端协作开发时,常常有如下情景: 后端开发完毕在服务器上进行部署并给前端API文档. 前端在本地进行开发并向远程服务器上部署的后端发送请求.在这种开发过程中,如果前端想要一边开发一边测试接口,就需要使用跨域的方式. 3. 通过注解的方式允许跨域 非常简单,我们可以在Contro

springMVC对跨域问题的支持

springMVC框架在4.2的版本之后对跨域问题有了支持,添加了@CrossOrigin注解来解决跨域问题 使用步骤: 1.正常的配置springMVC框架 1.1导入maven依赖 1.2编写核心配置文件 1.3配置web.xml文件 1.4编写controller 2.在controller上或者请求处理方法上添加@CrossOrigin注解,注意:要明确指定请求处理方法对应的请求方式,而不能使用默认的不指定方式. 必须得明确指定请求方法!!! 这样就可以简单的解决跨域问题了. 原文地址: