启用从AngularJS泽西CORS POST请求 [英] Enable CORS Post Request from AngularJS to Jersey

查看:279
本文介绍了启用从AngularJS泽西CORS POST请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从AngularJS应用泽西岛REST服务发布JSON文件。请求失败,通知我说:

I'm attempting to post a JSON document from an AngularJS app to a Jersey REST service. The request fails, informing me that:

XMLHtt prequest无法加载的http://本地主机:8080 / my.rest.service / API /顺序/ addOrder。无访问控制允许来源标头的请求的资源present。原产地的http:// localhost'的,因此不允许访问

我已经启用了(我认为是)适当的标题:访问控制允许来源访问控制 - 可以让方法的响应,如在下面的方法:

I have enabled (what I believe to be) the appropriate headers: Access-Control-Allow-Origin and Access-Control-Allow-Methods on the response, as seen in the method below:

@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/addOrder")
public Response addOrder(DBObject dbobject) {
    DB db = mongo.getDB("staffing");
    DBCollection col = db.getCollection("orders");
    col.insert(dbobject);
    ObjectId id = (ObjectId)dbobject.get("_id");
    return Response.ok()
            .entity(id)
            .header("Access-Control-Allow-Origin","*")
            .header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
            .allow("OPTIONS")
            .build();
}

角JS控制器

我已经声明了应用程序和配置$ httpProvider所有的设置类似的堆栈溢出问题建议:

Angular JS Controller

I've declared the app and configured the $httpProvider with all of the settings suggested in similar Stack Overflow questions:

var staffingApp = angular.module('myApp', ['ngRoute', 'ui.bootstrap']);
myApp.config(['$httpProvider', function ($httpProvider) {
    $httpProvider.defaults.useXDomain = true;
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
    $httpProvider.defaults.headers.common["Accept"] = "application/json";
    $httpProvider.defaults.headers.common["Content-Type"] = "application/json";
 }]);

我也创造了这个控制器打开一个模式和处理方式:

I've also created this controller to open a modal and handle the form:

    var modalCtrl = function($scope, $modal, $log, $http, $location) {          
    $scope.order = {
        activityTitle : null,
        anticipatedAwardDate : null,
        component : null,
        activityGroup : null,
        activityCategory : null,
        activityDescription : null
    };
    $scope.open = function () {
        var modalInstance = $modal.open({
            templateUrl: 'addOrder.html',
            windowClass: 'modal',
            controller: modalInstanceCtrl,
            resolve: {
                order : function () {
                    return $scope.order;
                    }
                }
            });
        modalInstance.result.then(function (oid) {
            $log.info("Form Submitted, headed to page...");
            $location.path("/orders/" + oid);
        }, function() { 
            $log.info("Form Cancelled")
        });
    };
};

var modalInstanceCtrl = function ($scope, $modalInstance, $log, $http, order) {
    $scope.order = order,
    $scope.ok = function () {
        $log.log('Submitting user info');
        $log.log(order);
        $log.log('And now in JSON....');
        $log.log(JSON.stringify(order));
        $http.post('http://localhost:8080/my.rest.service/api/order/addOrder', JSON.stringify(order)).success(function(data){
            $log.log("here's the data:\n");
            $log.log(data);
            $modalInstance.close(data._id.$oid)
        });
    };
    $scope.cancel = function () {
        $modalInstance.dismiss('cancel');
    };      
};
myApp.controller('modalCtrl', modalCtrl);

要无果,我已经试过:


  • 删除 .allow(「购股权」)从响应头。

  • 从应用程序移除$ httpProvider配置

  • 改$ httpProvider配置调用myApp.config(函数($ httpProvider){...}),传递函数本身,而不是数组。

得到相同的配置要求的工作:

Get requests work with the same configuration:

@GET
@Path("/listall/")
@Produces(MediaType.APPLICATION_JSON)
public Response listAll(){
    DB db = mongo.getDB("staffing");
    DBCollection col = db.getCollection("orders");
    List<DBObject> res = col.find().limit(200).toArray();
    return Response.ok()
            .entity(res.toString())
            .header("Access-Control-Allow-Origin","*")
            .header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
            .allow("OPTIONS")
            .build();       
}

这个控制器正常工作:

with this controller that works fine:

myApp.controller('orderListCtrl', function ($scope, $http){
    $http.get('http://localhost:8080/my.rest.service/api/order/listall').success(function(data) {
        for (var i = 0; i < data.length; i++) {
            if (data[i].description.length > 200) {
                data[i].shortDesc = data[i].description.substring(0,196) + "...";
            } else {
                data[i].shortDesc = data[i].description;
            }
        };
        $scope.orders = data;
    });
});

更新#1:

我已经尝试了同一产地的基础上了同样的要求,从根本上服务于从旁边的的locahost REST服务的角度应用:8080。这种配置工作,但需要一个细微的变化和一些通用在我的code,这上面我编辑的清理。

Update #1:

I've tried the same request on a same origin basis, essentially serving the Angular application alongside the REST service from locahost:8080. This configuration worked, but required a slight change and some general clean up in my code, which I've edited above.

岗位仍不能作为CORS请求,但让我仍然在寻找在这个配置中缺少的部分。

The Post still fails as a CORS request, however so I'm still looking for the missing piece in this configuration.

我已经调查工作请求的头,因为他们正在与非工作的请求传递到浏览器和他们相比。

I've investigated the headers of the working request as they're delivered to the browser and compared them with the non-working request.

该工作得到请求返回其响应以下标题:

The working get request returns the following headers with its response:

非工作后请求返回头与它的响应,但缺少访问控制允许来源标题:

The non-working post request returns headers with its response, but is missing the Access-Control-Allow-Origin header:

我相信这现在已经成为头一个问题被前将其返回到客户端,那么这将导致浏览器请求失败剥下的响应。

I believe this has now become an issue of the headers being stripped off of the response prior to returning it to the client, which would then cause the browser to fail the request.

提交测试POST请求从Chrome的REST控制台扩展相同的URL返回相应的响应头,如下面的撷取画面看到。

Submitting a test POST request to the same URL from Chrome's REST Console extension returns the appropriate response headers, as seen in the screencap below.

在这一点上,我不能确定是什么去除新泽西州和我的角客户端之间的头,但我相当有信心,这就是罪魁祸首。

At this point, I can't determine what's removing the headers between Jersey and my Angular client, but I'm fairly confident that's the culprit.

推荐答案

原来,这个问题是选项的处理不够请求pre-飞行之前,用适当的十字起源头中的POST请求发送。

The problem turned out to be inadequate handling of the OPTIONS request sent in pre-flight prior to the POST request with the proper cross origin headers.

我可以通过下载和执行在本页面发现CORS过滤器来解决问题:<一href=\"http://software.dzhuvinov.com/cors-filter-installation.html\">http://software.dzhuvinov.com/cors-filter-installation.html.

I was able to resolve the issue by downloading and implementing the CORS filter found at this page: http://software.dzhuvinov.com/cors-filter-installation.html.

如果您遇到了类似的问题,按照说明和测试,看看你的OPTIONS请求不再失败,并立即后跟您成功的请求。

If you're experiencing a similar problem, follow the instructions and test to see that your OPTIONS request is no longer failing, and is immediately followed by your successful request.

这篇关于启用从AngularJS泽西CORS POST请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆