Ajax跨域之ContentType为application/json请求失败的问题
项目里的接口都是用springmvc写的,其中在@requestmapping接口中定义了consumes="application/json",也就是该接口只接受ContentType为application/json的请求。
接口写好用工具测试接口都是可以正常请求,但是在浏览器中用ajax请求就不行。
百度一下,原来在使用Ajax跨域请求时,如果设置Header的ContentType为application/json,会分两次发送请求。第一次先发送Method为OPTIONS的请求到服务器,这个请求会询问服务器支持哪些请求方法(GET,POST等),支持哪些请求头等等服务器的支持情况。等到这个请求返回后,如果原来我们准备发送的请求符合服务器的规则,那么才会继续发送第二个请求,否则会在Console中报错。
为什么在跨域的时候设置ContentType为application/json时会请求两次?其实JQuery的文档对此有做说明。
contentType (default: 'application/x-www-form-urlencoded; charset=UTF-8')
Type: Boolean or String
When sending data to the server, use this content type. Default is "application/x-www-form-urlencoded; charset=UTF-8", which is fine for most cases. If you explicitly pass in a content-type to $.ajax(), then it is always sent to the server (even if no data is sent). As of jQuery 1.6 you can pass false to tell jQuery to not set any content type header. Note: The W3C XMLHttpRequest specification dictates that the charset is always UTF-8; specifying another charset will not force the browser to change the encoding. Note: For cross-domain requests, setting the content type to anything other than application/x-www-form-urlencoded, multipart/form-data, or text/plain will trigger the browser to send a preflight OPTIONS request to the server.
注意Note后面的描述,在跨域的时候,除了contentType为application/x-www-form-urlencoded,multipart/form-data或者text/plain外,都会触发浏览器先发送方法为OPTIONS的请求。
比如说,你原来的请求是方法方法POST,如果第一个请求返回的结果Header中的Allow属性并没有POST方法,那么第二个请求是不会发送的,此时浏览器控制台会报错,告诉你POST方法并不被服务器支持。
图中箭头指向的Allow就是服务器返回的支持的方法。
不仅如此,如果想要用ContentType:application/json发送跨域请求,服务器端还必须设置一个名为Access-Control-Allow-Headers的Header,将它的值设置为 Content-Type,表明服务器能够接收到前端发送的请求中的ContentType属性并使用它的值。否则第二次请求也是发不出去的,浏览器console会报错,并提示你服务器没有设置Access-Control-Allow-Headers。
对应到我java程序的filter过滤器里是这样
public class MyFilter implements Filter { @Override
public void destroy() {
//System.out.println("过滤器销毁");
} @Override
public void doFilter(ServletRequest request, ServletResponse response,
HttpServletRequest httpRequest = (HttpServletRequest) request;
String type=httpRequest.getMethod(); if (type.toUpperCase().equals("OPTIONS")==true) {
httpResponse.setHeader("Access-Control-Allow-Headers", "content-type, accept");
15 httpResponse.setHeader("Access-Control-Allow-Methods", "POST");
16 httpResponse.setStatus(200);
17 httpResponse.setContentType("text/plain;charset=utf-8");
18 httpResponse.setCharacterEncoding("utf-8");
responseContentByte="{\"test\":\"OPTIONS\"}".getBytes();
}
} @Override
public void init(FilterConfig arg0) throws ServletException {
//System.out.println("过滤器初始化");
} }
Ajax跨域之ContentType为application/json请求失败的问题的更多相关文章
- Ajax 跨域,这应该是最全的解决方案了
https://segmentfault.com/a/1190000012469713 前言 从刚接触前端开发起,跨域这个词就一直以很高的频率在身边重复出现,一直到现在,已经调试过N个跨域相关的问题了 ...
- ajax跨域,这应该是最全的解决方案了
前言 从刚接触前端开发起,跨域这个词就一直以很高的频率在身边重复出现,一直到现在,已经调试过N个跨域相关的问题了,16年时也整理过一篇相关文章,但是感觉还是差了点什么,于是现在重新梳理了一下. 个人见 ...
- ajax 跨域----好用的解决方案
一.前言 跨域这个词就一直以很高的频率在身边重复出现,一直到现在,已经调试过N个跨域相关的问题了! 但是感觉还是差了点什么,于是现在重新梳理了一下.个人见识有限,如有差错,请多多见谅 二.前言 关于跨 ...
- ajax跨域 (转)
题纲 关于跨域,有N种类型,本文只专注于ajax请求跨域(,ajax跨域只是属于浏览器”同源策略”中的一部分,其它的还有Cookie跨域iframe跨域,LocalStorage跨域等这里不做介绍), ...
- Ajax跨域解决方案大全
题纲 关于跨域,有N种类型,本文只专注于ajax请求跨域(,ajax跨域只是属于浏览器"同源策略"中的一部分,其它的还有Cookie跨域iframe跨域,LocalStorage跨 ...
- 一篇关于ajax跨域问题的解决方案
这几天没事,我有一个好友,让我帮他做一个机器人对话demo, 我说 看看有没有时间(其实自己一脸懵逼) 然后百度了一下,发现了一个机器人 -(连接就不弄出来了,可以私底下交流) ,,我是用这个的 好 ...
- Ajaxadr ajax跨域请求crossdomain
最近工作需要用到ajax跨域请求参数,网上找很很久,最终得到解决之道.分享一下吧,希望能帮到各位 也许你已经发现在浏览器直接敲路径能获得对方提供接口的参数,而一到项目中Ajax请求却老是失败.原因是, ...
- JQuery.Ajax + 跨域 (crossDomain) + POST + JSON + WCF RESTful, 5大陷阱和解决方案
JQuery.Ajax + 跨域 (crossDomain) + POST + JSON + WCF RESTful, 5大陷阱和解决方案 最近在开发WSS RESTful服务的时候, 碰到了这些个纠 ...
- 说说JSON和JSONP,浅析JSONP解决AJAX跨域问题
说到AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交换数据?第二个是跨域的需求如何解决?这两个问题目前都有不同的解决方案,比如数据可以用自定义字符串或者用XML来描述,跨域可以通过服 ...
随机推荐
- TCP的核心系列 — SACK和DSACK的实现(四)
和18版本不同,37版本把DSACK的检测部分独立出来,可读性更好. 37版本在DSACK的处理中也做了一些优化,对DSACK的两种情况分别进行处理. 本文主要内容:DSACK的检测.DSACK的处理 ...
- Android开发技巧——使用Dialog实现仿QQ的ActionSheet菜单
最近看到有人用Dialog来实现QQ的仿ActionSheet的自定义菜单,对于自己没实现过的一些控件,看着也想实现一下.于是动手了一下,发现也不难,和大家分享一下. 本文原创,转载请注明出处:htt ...
- Media Player Classic - HC 源代码分析 3:核心类 (CMainFrame)(2)
===================================================== Media Player Classic - HC 源代码分析系列文章列表: Media P ...
- LAV Filter 源代码分析 4: LAV Video (2)
上一篇文章分析了LAV Filter 中的LAV Video的两个主要的类:CLAVVideo和CDecodeThread.文章:LAV Filter 源代码分析 3: LAV Video (1) 在 ...
- 苹果新的编程语言 Swift 语言进阶(二)--基本数据类型
一 . 常量和变量 Swift语言 对常量和变量的声明进行了明确的区分 Swift语言的常量类型比C 语言的constants类型更加强大,语义更加明确. 常量和变量的区别是常量在设置或初始化后 ...
- iOS9 ReplayKit录制视频
猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/50260873 ...
- Leetcode_257_Binary Tree Paths
本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/49432057 Given a binary tree, r ...
- asp.net 调试与iis部署的问题
第一个问题:编译器错误信息: CS0016: 未能写入输出文件"c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET ...
- 我对IoC/DI的理解
IoC IoC: Inversion of Control,控制反转, 控制权从应用程序转移到框架(如IoC容器),是框架共有特性 1.为什么需要IoC容器 1.1.应用程序主动控制对象的实例化及依赖 ...
- oracle to_date 函数
update pamsodt0p10 set cursysdate = to_date('2014-12-29 00:00:00','yyyy-mm-dd hh24:mi:ss') where cu ...