Angular: Custom headers are ignored by $http and $resource. Why?

前端 未结 3 1557
夕颜
夕颜 2021-02-14 21:23

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 und

相关标签:
3条回答
  • 2021-02-14 21:38

    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).

    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:

    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.

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

    Some more background info:

    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);
    })
    

    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>
    

    The content of the response to http://headers.jsontest.com/?callback=angular.callbacks._1 will be:

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

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

    0 讨论(0)
  • 2021-02-14 21:50

    While what you have is supposed to work according to the docs, my experience has been a bit different. To get around this issue, we did the following:

    Create a "base controller" that gets added to the page either on the body or html tag. In that controller, make the assignment using $http instead of $httpProvider. Because your base controller loads when the initial page loads, it is there for all other controllers and services that will run in your app.

    I don't know why this works and the proscribed method does not, and I'd love to see an answer to your question that is better than this work-around, but at least this can get you moving forward with development again.

    0 讨论(0)
  • 2021-02-14 21:59

    The following works for me - however, I do that during "runtime" with $http and I am not using $httpProvider during bootstrapping.

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

    Edit

    Here is a working jsFiddle version. Check the request which is done with Developer Tools/Firebug and see that "application/json, text/javascript" is requested.

    0 讨论(0)
提交回复
热议问题