角:自定义标题由$ http和$资源忽略。为什么? [英] Angular: Custom headers are ignored by $http and $resource. Why?
问题描述
我试图访问一个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屋!