角:自定义标题由$ http和$资源忽略。为什么? [英] Angular: Custom headers are ignored by $http and $resource. Why?

查看:257
本文介绍了角:自定义标题由$ http和$资源忽略。为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图访​​问一个REST服务,我无法控制。第一个问题是服务不包括访问控制允许来源的头,这是这样的,如果我理解正确的话,马上会限制我JSONP的问题。

I'm trying to access a REST service I don't control. First problem is that the service doesn't include a Access-Control-Allow-Origin header, which is a problem that, if I understand correctly, immediately limits me to JSONP.

此外,在默认情况下,该服务发送XML而不是JSON,虽然它能够发送JSON的。我觉得应该给我的Accept头回应,负责服务的人说,它看起来在我的Content-Type。这将意味着我需要做一个POST,而不是GET(虽然GET使得当我刚开始一些静态的数据更有意义,对吧?)。

Also, by default, this service sends XML rather than JSON, though it's capable of sending JSON. I think it should respond to my Accept header, the people responsible for the service say it looks at my Content-Type. That would mean I'd need to do a POST rather than a GET (though get makes more sense when I'm just getting some static data, right?).

固执,因为我,我想我的第一个接受头。由于角只接受JSON,我希望它使用接受:默认情况下,应用程序/ JSON 头,但它没有,它忽略了我的努力来进行设置手动:

Stubborn as I am, I'm trying my Accept header first. Since Angular only accepts JSON, I'd expect it to use the Accept: application/json header by default, but it doesn't, and it ignores my attempts to set it manually:

app.config(['$httpProvider', function($httpProvider){
    console.log($httpProvider.defaults.headers.common);
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
    $httpProvider.defaults.headers.post['Accept'] = 'application/json, text/javascript';
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/json; charset=utf-8';
    $httpProvider.defaults.headers.post['Access-Control-Max-Age'] = '1728000';
    $httpProvider.defaults.headers.common['Access-Control-Max-Age'] = '1728000';
    $httpProvider.defaults.headers.common['Accept'] = 'application/json, text/javascript';
    $httpProvider.defaults.headers.common['Content-Type'] = 'application/json; charset=utf-8';
    $httpProvider.defaults.useXDomain = true;
}]);

我在实际的资源再次做到这一点:

I do this again in the actual resource:

return $resource('http://foo.com/getStuff', {}, {
    fetch: {
        method:'JSONP',
        params: params,
        headers: {
            'Accept':'application/json, text/javascript',
            'Content-Type':'application/json; charset=utf-8'
        },
        isArray:false,
        callback: 'JSON_CALLBACK'
    }
});

但尽管如此,请求头包含接受:* / *

我的问题是:为什么?为什么角忽略我的头?我如何得到它无论如何使用正确的头?

My question is: WHY? Why does Angular ignore my headers? And how do I get it to use the proper headers anyway?

和也:有没有在POST使用JSONP的方式

And also: is there a way to use JSONP in a POST?

编辑:最初我用角1.0.7,但我只是尝试了1.2.3,并得到了相同的结果。头被忽略,然而每个人都声称,这是做它的方式。

Originally I used Angular 1.0.7, but I just tried it with 1.2.3 and got the same results. Headers are ignored, yet everybody claims that this is the way to do it.

我也试过直接与$ HTTP这样做,而不是$资源,具有相同的结果。

I also tried doing it directly with $http, rather than with $resource, with the same results.

编辑2:这里有一个的jsfiddle 。它的匿名,并且不使用我的真正的服务器,但使用Firebug /开发工具,你可以验证它发送接受:* / *,在两个通话,尽管我多次尝试设置应用程序/ JSON 头。而且这是我真正的问题。在我的真实服务器,我得到正因为如此XML结果,尽管我真正的服务器来发送JSON的能力。

Edit 2: Here's a JSFiddle. It's anonymized and doesn't use my real server, but using Firebug/developer tools, you can verify that it sends Accept: */* on both calls, despite my many attempts to set application/json headers. And that is my real problem here. On my real server, I'm getting an XML result because of that, despite my real server's ability to send JSON.

(无论是真实的服务器支持JSONP是目前较少有关。这个虚拟的服务器显然没有,不过没关系,我只关心头。)

(Whether the real server supports jsonp is less relevant at the moment. This dummy server clearly doesn't, but that's okay. I just care about the headers.)

修改3:我已经试过这两种解决方案以下建议:

Edit 3: I've tried both solutions suggested below:

$http.defaults.headers.common['Accept'] = 'application/json, text/javascript';

$http.defaults.transformRequest.push(function (data, headersGetter) {
    headersGetter().Accept = "application/json, text/javascript";
    return data;
});

我试过分开两个语句。在控制器中,然后在服务只是http之前调用本身。仍然无法正常工作。

I've tried both statements separately. In the controller, and then in the service just before the http call itself. Still doesn't work.

有人可以给我一个的jsfiddle这何处显示工作?

Can someone give me a JsFiddle where this is shown to work?

修改4:我注意到,当我使用GET而不是JSONP,接收报头是正确的。但随后的响应将被拒绝,因为它不具有正确的报头

Edit 4: I notice that when I use GET rather than JSONP, the Accept header is correct. But then the response is rejected because it doesn't have the correct header.

应该在JSONP调用有什么样的头?因为有在JSONP调用了很多头,但没有将其标识为JSONP。服务器是否必须有明确的JSONP支持这个工作?我突然意识到我不知道远远不够约JSONP。

What kind of headers should a JSONP call have? Because there's a lot more headers in the JSONP call, but nothing that identifies it as JSONP. Does the server have to have explicit JSONP support for this to work? I suddenly realize I don't know nearly enough about jsonp.

推荐答案

我觉得你的回答是<一个href=\"http://stackoverflow.com/questions/11725591/how-to-use-datatype-jsonp-but-still-have-application-json-in-accept-header\">here.脚本&GT; 维基,A JSONP呼叫通过的&LT注射执行code>标签从主机服务器,它通过调用回调函数,传递数据响应加载脚本。 A &LT;脚本&GT; 标记生成一个普通浏览器请求(不是 XmlHtt prequest ),并在浏览器将派出自己的Accept头(它也发送它自己的User-Agent头,例如)。

I think your answer is here. According to the wiki, A JSONP call is executed through injection of a <script> tag to load the script from the host server, which responds by calling your callback, passing the data. A <script> tag generates a regular browser request (not an XmlHttpRequest), and the browser will send its own Accept header (it also sends its own User-Agent header, for example).

我希望有一个更简单的客户端的方式来做到这一点,但我认为唯一的办法可能是一个在<建议href=\"http://stackoverflow.com/questions/11725591/how-to-use-datatype-jsonp-but-still-have-application-json-in-accept-header\">the引用帖子:

I would hope there is an easier client-side way to do this, but I think the only way may be the one suggested in the referenced post:

所以,如果你希望能够设置跨域调用请求头
  你将不得不设置你的域服务器端脚本,将
  委托调用远程域(并设置相应的
  头),然后发送AJAX请求到脚本。

So, if you want to be able to set request headers for cross domain calls you will have to setup a server side script on your domain that will delegate the call to the remote domain (and set the respective headers) and then send the AJAX request to your script.

编辑:这里 是(拒绝)jQuery的错误有关此相同的问题报告

here is a (rejected) jQuery bug report about this same problem.

一些更多的背景信息:

在角,回调会被自动管理,因此,如果你这样说:

In angular, callbacks are managed automagically, so if your say this:

$http({
    method: "JSONP",
    url: "http://headers.jsontest.com?callback=JSON_CALLBACK",
}).success(function(data) {
    console.log('Return value:');
    console.log(data);
}).error(function(data) {
    console.log('Error!');
    console.log(data);
})

&LT;脚本&GT; 标签将创建一个看起来或多或少是这样的:

a <script> tag will be created that looks more or less like this:

<script type="application/javascript"
        src="http://headers.jsontest.com/?callback=angular.callbacks._1">
</script>

响应后 http://headers.jsontest.com/?callback=angular.callbacks._1 内容将是:

angular.callbacks._1({key1: "value1", key2: "value2"});

angular.callbacks._1 将包含成功函数,它将与数据被调用。

angular.callbacks._1 will contain your success function, and it will be called with the data.

这篇关于角:自定义标题由$ http和$资源忽略。为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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