跨域问题实战 2

跨域问题实战 2


背景

由于整个项目提供出去的API都不是跨域的只是个别是需要跨域的,所以再上一次跨域问题实战中,自己是直接再controller层其中需要提供出去跨域的方法里设置了HttpServletResponse.setHeader("Access-Control-Allow-Origin","*")。而且上次提供出去的只是一次简单的get请求,而不是复杂请求。但是呢,这次的需求是记录用户行为日志的一次跨域请求,也就是说是一次post请求。其中就涉及到http请求的Content-Type中application/json和application/x-www-form-urlencoded。还涉及到springMVC中的@RequestBody这个注解。其中这些问题,就下一篇博客再详细记录。因为涉及到post中的application/json所以就涉及到跨域的复杂请求。

问题重现

由于ajax默认的contentType是application/x-www-form-urlencoded。所以自己对这次请求设置的是application/json

代码如下


    var data = {
        "userId" : 20142100122,
        "userOperationStep" : 2,
        "appPlatform": "android",
        "app" : 0,
        "videoId":123123
    };

    $.ajax({
        url : ‘http://xxxxxx/xxxxc/xxx/vippromotion‘,
        type : ‘POST‘,
        dateType : ‘json‘,
        contentType : ‘application/json‘,
        data:JSON.stringify(data),
        success : function(msg){
            console.log(msg);
        }
    })

由于自己只想让该接口可以被进行跨域操作所以自己再controller层是单独设置的跨域请求的

部分代码如下

 public Json vippromotion(@RequestBody VipPromotionLog vipPromotionLog, HttpServletResponse response){
        response.setHeader("Access-Control-Allow-Headers","Origin, X-Requested-With, Content-Type, Accept");
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Allow","POST");
        response.setHeader("Access-Control-Allow-Credentials ", "true");
        .......

}

看清楚自己这里设置了Access-Control-Allow-Headers允许了复杂请求,但是却出现如下错误

如图一

图一

但是Ajax请求却没有失败。如图二

图二

排查

由于自己再该接口中设置了允许复杂请求,但是却根本没有进来,所以并不是跨域代码错误。这里就得说一下什么是复杂请求了。复杂请求是会进行两次请求得,一次是预请求,一次是真正得请求。 从上面得例子可以看出,自己只是对真正得请求进行跨域处理,但是却没有对预请求进行跨域处理。所以导致跨域失败。

解决

设置过滤器,对每次进行进行跨域处理代码如下

  @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse res, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("doFilter--------------start");
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Allow","POST");
        response.setHeader("Access-Control-Allow-Headers","Origin, X-Requested-With, Content-Type, Accept");
        response.setHeader("Access-Control-Allow-Credentials ", "true");
        System.out.println("doFilter--------------end");
        filterChain.doFilter(servletRequest, res);
    }

web.xml中得我就不贴了。

运行项目发起请求,请求处理如下图三:

图三

看到了没有两次请求。

然后我们再发起一次请求来看一下,结果如下图四

图四

只有一次请求,这是因为设置了 response.setHeader("Access-Control-Max-Age", "3600");6分钟内不用再发起预请求。

防止

如果是一个单独给外界提供接口得项目得话,我建议设置一个跨域处理得过滤器。如果只是一个项目中一两个接口是提供给别人得,别人是跨域操作得话,尽量是简单请求。就是用ajax中默认得参数application/x-www-form-urlencoded

原文地址:https://www.cnblogs.com/Krloypower/p/9277053.html

时间: 2024-07-30 05:14:52

跨域问题实战 2的相关文章

js中各种跨域问题实战小结(二)

这里接上篇:js中各种跨域问题实战小结(一) 后面继续学习的过程中,对上面第一篇有稍作休整.下面继续第二部分: -->5.利用iframe和location.hash -->6.window.name跨域实现 利用iframe和location.hash实现跨域 想必有很多人像我之前一样,或许只知道上面文中所说的那几种方法.所以,我刚了解到可以用iframe和location.hash来实现跨域的时候,我会想,为什么他们可以实现.iframe是什么,有什么特性,location.hash是什么

js中各种跨域问题实战小结

什么是跨域?为什么要实现跨域呢? 这是因为JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.也就是说只能访问同一个域中的资源.我觉得这就有必要了解下javascript中的同源策略是怎么回事了:javascript的同源策略 于是当我们想某些特定的功能的时候,实现合理的跨域请求就显得比较重要了. -->1.原生Ajax对象xhr的跨域 -->2.简单jsonp -->3.图像Ping -->4.document.domain+iframe实现跨域 javascr

跨域问题实战

背景 公司最近有这样一个需求,XXX用前后端分离的技术实现.用Restful api风格. 问题出现 写好的http接口提供给前段人员处理出现如下图:错误图一 $$错误图一1$$ 错误描述: no Access-Control-Allow-Origin is present on the requested resource. Orgin 'http:localhost:8080' is therefore not allowed access 字面意思是 没有访问控制允许源在请求的资源上.没有

2018 Vue+Django API前后端分离开发电商新技术跨域项目实战

课程目标帮助大家快速入门Django REST framework这一个API框架. 帮助大家详细了解Django REST framework中序列化.视图.路由等模块的使用. 帮助大家使用Django REST framework快速开发一套可用的API服务,并且自动生成API文档.适用人群Python开发工程师,后端开发工程师课程简介目前前后端分离的架构设计越来越流行,前后端通过API来实现数据通信.那如何快速开发一套符合RESTful风格的API呢?Django REST framewo

跨域MPLS 虚拟私有网络的Option 2 解决方案全实战

跨域MPLS ×××的Option 2 解决方案实战 读者如果要完成Option2的实施,可以在Option1的基础上完成,也可以在构建完毕两个AS内部的MPLS ×××之后来实施.Option2和Option1的区别在于在ASBR上不在需要VRF的实施,而直接通过直连路由在ASBR之间构建MP-EBGP的×××V4邻居关系,即通过BGP更新两侧AS的客户路由:同时在ASBR之间为标签转发,而不在是IP转发8.2.1 Option2中ASBR之间构建×××v4的EBGP邻居请读者自行去掉ASBR

Redis实战和核心原理详解(5)使用Spring Session和Redis解决分布式Session跨域共享问题

Redis实战和核心原理详解(6)使用Spring Session和Redis解决分布式Session跨域共享问题 前言 对于分布式使用Nginx+Tomcat实现负载均衡,最常用的均衡算法有IP_Hash.轮训.根据权重.随机等.不管对于哪一种负载均衡算法,由于Nginx对不同的请求分发到某一个Tomcat,Tomcat在运行的时候分别是不同的容器里,因此会出现session不同步或者丢失的问题. 实际上实现Session共享的方案很多,其中一种常用的就是使用Tomcat.Jetty等服务器提

3.2.3、Google Tag Manager实战指南—— 跨域跟踪

如果您使用统一版跟踪代码,即analytics.js,这个已经默认开启了跨子域跟踪的,可以直接使用跟踪代码,如图3-41所示,但还需要配置一些东西: 图3-41 跟踪代码里面的auto表示自动将Cookie生成在顶级域名之下,也就是两个子域会是共用同一个顶级域名里的Cookie了.如果您是用GTM管理的,直接配置CookieDomain就行了,这个的作用就是前面auto,设置如图3-42所示: 图3-42 配置CookieDomain 上面两种方法都是实现同样的作用,接下来就是引荐流量排除了,使

跨域访问之JSONP

跨域 在平常的工作中常常会遇到A站点的需要访问B站点的资源. 这时就产生了跨域访问. 跨域是指从一个域名的网页去请求另一个域名的资源.浏览器遵循同源策略,不允许A站点的Javascript 读取B站点返回的数据.因为A站点的javascript 与B返回的数据不同源的.但是浏览器并不阻止A的Ajax请求访问B,浏览器允许A取回B的数据,但是不允许A中的脚本操作B的数据.如下图所示的③ 同源策略: 数据与操作必须是同源的,否则不能操作. 什么是同源:浏览器认为的同源是什么? 判断是否同源,标准如下

【ajax跨域】原因原理解决

1.安全,跨域cookie iframe 2.很简单,就是利用<script>标签没有跨域限制的“漏洞”(历史遗迹啊)来达到与第三方通讯的目的.当需要通讯时,本站脚本创建一个<script>元素,地址指向第三方的API网址,形如: <script src="http://www.example.net/api?param1=1&param2=2"></script> 并提供一个回调函数来接收数据(函数名可约定,或通过地址参数传递)