AJAX POST To Jersey 启用 RESTful Web 服务跨域

Posted

技术标签:

【中文标题】AJAX POST To Jersey 启用 RESTful Web 服务跨域【英文标题】:AJAX POST To Jersey enabled RESTful Webservice Cross Domain 【发布时间】:2015-08-22 23:54:42 【问题描述】:

我正在开发一个 Cordova/PhoneGap 应用程序,用于与现有的 Restful Web 服务 (Jersey) 通信。 Web 服务很好,因为我已经开发了我的应用程序的 android 版本并且它工作正常。现在我正在开发基于 ios 的 Cordova。我已经阅读了有关 CORS 的内容以及有关跨域 AJAX 调用的相关内容。但是发送 AJAX 请求会导致以下错误:

XMLHttpRequest 无法加载 http://xxxx:xxxx/api/v1/general/authenticate1。不 请求中存在“Access-Control-Allow-Origin”标头 资源。因此不允许访问 Origin 'null'。

此外,在服务器端日志中,每个 AJAX 调用都会使用以下消息创建一堆日志:

信息:找不到类的语法元素 com.test.database.PeopleAuth 2015 年 6 月 8 日下午 5:49:07 com.sun.jersey.server.wadl.generators.AbstractWadlGeneratorGrammarGenerator 附加类型

请检查以下代码并告诉我这里有什么问题。

这是我在客户端的 AJAX 代码:

var j = IMEI: ximei, IMSI: ximsi; 
var d = JSON.stringify(j);
console.log(d);
$.ajax(
    url:baseurl,
    contentType: "application/json; charset=utf-8",
    dataType:'json',     
    type:'POST',
    crossDomain: true,
    data: d,
    success:function(callbak) 
        console.log(callbak);
    ,
    error:function(XMLHttpRequest,textStatus, errorThrown) 
        console.log(XMLHttpRequest);
        //console.log(textStatus);
        //console.log(errorThrown);
    
);

这是我为 CORS 标头内容添加的 Web 服务过滤器

@Provider
public class CORSResponseFilter implements ContainerResponseFilter  

    @Override
    public ContainerResponse filter(ContainerRequest requestContext, ContainerResponse responseContext) 

        responseContext.getHttpHeaders().putSingle("Access-Control-Allow-Origin", "*");
        //responseContext.getHttpHeaders().putSingle("Access-Control-Allow-Credentials", "true");
        responseContext.getHttpHeaders().putSingle("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS, HEAD");
        responseContext.getHttpHeaders().putSingle("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With");

        return responseContext;
    


还有 web.xml

<servlet>
    <servlet-name>TEST REST Service</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>com.test.pckg</param-value>
    </init-param>
    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>com.sun.jersey.api.container.ContainerResponseFilters</param-name>
        <param-value>com.test.webservices.CORSResponseFilter</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

更新 #1: 我已经使用 Rest Console(Google Chrome 扩展)测试了 Web 服务,它们工作正常。

【问题讨论】:

您的包裹扫描&lt;init-param&gt; 错误。这个jersey.config.server.provider.packages 应该是com.sun.jersey.config.property.packages @peeskillet 感谢您的回复,但我认为情况并非如此,因为正如我所说的那样,webservices 可以很好地处理来自 android 的请求 如果您的应用程序正在使用 init-param(这是错误的),那么您的整个 web.xml 可能毫无用处。尝试将 @Provider 添加到 CORS 过滤器。日志中还有任何异常还是全部是信息日志? @peeskillet,我会测试你说的,日志都是INFO日志 我已将@Provider 添加到 CORSFilter,但什么也没发生,结果相同 【参考方案1】:

我通过使用 CORPS 库解决了这个问题。 在dzhuvinov 阅读更多内容,和我的here 一样的问题。

问题解决了,但我不知道为什么,很想知道(寻找它),如果有人知道请评论。

【讨论】:

【参考方案2】:

对于跨域,您需要使用 JSONP 而不是 JSON 作为类型。确保这也支持服务器端代码。

改变

dataType:'json',

dataType: 'jsonp'

请参阅此处了解区别 Difference between dataType jsonp and JSON

【讨论】:

以上是关于AJAX POST To Jersey 启用 RESTful Web 服务跨域的主要内容,如果未能解决你的问题,请参考以下文章

启用从 jQuery ajax 到不在 IIS 中托管的 WCF 服务的 CORS POST

Ajax Post to Overloading c# web service方法

jersey rest post 访问为http 405 异常如何解决

启用从 AngularJS 到 Jersey 的 CORS 发布请求

Jax-rs -jersey 跨域请求启用

Jersey实现Client端:GET/PUT/POST/DELETE