如何让第一个预先发出的POST请求成功完成并将响应发送回我的jQuery $ .ajax()方法?
当我使用CORS和Tomcat时,我发送的第一个帖子请求挂起。由于我的请求是预先通知的,因此它会触发CORS。根据Chrome开发者窗口中的“网络”标签,OPTIONS预检请求成功完成,但POST请求保持待定状态。
奇怪的是,servlet收到了POST请求,servlet完成了请求。然而,servlet或其他我不知道的东西,并没有向我的客户端发回响应,因此客户端挂起,等待对原始POST请求的响应。
即使更奇怪,同一网址的第二个POST 请求也会成功完成,并会为第二个POST请求返回响应。在第二个请求之前没有OPTIONS握手,因为浏览器缓存了预检请求,因为我将cors.maxAge
设置为3600.第二个请求必须使用从原始预检缓存的OPTIONS。
其他类似的SO问题:
有很多关于SO的问题谈论CORS,其中一些讨论使用Tomcat和CORS。
来自Ninefingers的一个很棒,但它出现在Python上。
来自James的另一个很好,但它似乎并不适用,因为我使用了更新版本的jQuery并指定了cors.maxAge
属性。
我的请求网址:http://myRESTAPIHost:8080/myServlet/LinkObject
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:myRESTAPIHost:8080
Origin:http://myClientUIHost:8080
Referer:http://myClientUIHost:8080/myClientServlet/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36
Response Headersview source
Access-Control-Allow-Headers:accept, content-type
Access-Control-Allow-Methods:PUT, DELETE, GET, POST, OPTIONS, HEAD
Access-Control-Allow-Origin:http://myClientUIHost:8080
Access-Control-Max-Age:3600
Content-Length:0
Date:Fri, 13 Jun 2014 19:11:01 GMT
Server:Apache-Coyote/1.1
Vary:Origin
Accept:application/json, text/javascript, */*; q=0.01
Content-Type:application/json;
Origin:http://myClientUIHost:8080
Referer:http://myClientUIHost:8080/myClientServlet/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36
Accept:application/json, text/javascript, */*; q=0.01
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:52
Content-Type:application/json;
Host:myRESTAPIHost:8080
Origin:http://myClientUIHost:8080
Referer:http://myClientUIHost:8080/ubmPrototype/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36
Access-Control-Allow-Origin:http://myClientUIHost:8080
Access-Control-Expose-Headers:X-Custom-1, X-Custom-2
Content-Type:application/json;charset=UTF-8
Date:Fri, 13 Jun 2014 19:16:57 GMT
Server:Apache-Coyote/1.1
Transfer-Encoding:chunked
Vary:Origin
objSave: function(restfulUrl, obj, opType, error, gridVar, dialog) {
$.ajax({
type : opType,
crossDomain : true,
url : "http://myRESTAPIHost/myServlet/" + restfulUrl,
data : JSON.stringify(obj),
contentType : "application/json;",
dataType : "json"
}).done(function(data) {
if(gridVar !== undefined && gridVar !== null)
gridVar.update();
if(dialog !== undefined && dialog !== null)
dialog.hide();
}).fail(function(){
console.log(error);
});
},
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.1"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<display-name>MyCORSfilter</display-name>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<filter>
<description>generated-persistence-filter</description>
<filter-name>CORSFilter</filter-name>
<filter-class>
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
</filter-class>
<init-param>
<param-name>entityManagerFactoryBeanName</param-name>
<param-value>myServlet</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>MyCORSFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<!-- The CORS filter with parameters -->
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
<!-- Note: All parameters are options, if omitted the CORS
Filter will fall back to the respective default values.
-->
<init-param>
<param-name>cors.allowGenericHttpRequests</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.allowOrigin</param-name>
<param-value>__all of my other hosts__, http://myClientUIHost:8080, http://myRESTAPIHost:8080</param-value>
</init-param>
<init-param>
<param-name>cors.allowSubdomains</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>cors.supportedMethods</param-name>
<param-value>GET, HEAD, POST, PUT, DELETE, OPTIONS</param-value>
</init-param>
<init-param>
<param-name>cors.supportedHeaders</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.exposedHeaders</param-name>
<param-value>X-Custom-1, X-Custom-2</param-value>
</init-param>
<init-param>
<param-name>cors.supportsCredentials</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>cors.maxAge</param-name>
<param-value>3600</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CORS</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<description>generated-servlet</description>
<servlet-name>myServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:myServlet-web-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<description>generated-resources-servlet</description>
<servlet-name>Resource Servlet</servlet-name>
<servlet-class>
org.springframework.js.resource.ResourceServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Resource Servlet</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>myServlet Servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
答案 0 :(得分:3)
这可能会让你们中的一些人大笑。
解决方案是在我的防病毒程序Sophos AV中关闭Web Protection。
请参阅论坛上的链接,了解发生在我身上的具体信息: http://community.sophos.com/t5/Sophos-EndUser-Protection/Sophos-9-0-7-breaks-browser-AJAX-CORS-support-in-Chrome-Firefox/m-p/46923/highlight/false#M17046
以下是来自rghazarian和Dominik的两个SO链接,但问题和解决方案相同。
捂脸!