Angular JS HTTP Response header not working on Safari - angularjs

I am stuck in a problem where I am posting an object, in response I should get some header from the HTTP response. The problem is this code is working fine in browsers like Chrome, Firefox, IE but it returns null in case of Safari (Windows).
$http.post(url, data)
.then(function(response){
console.log(response.headers("location"));
// response.headers("location") is null in Safari
});
Below are the response headers I am getting from the server.
Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://localhost:5000
Access-Control-Expose-Headers:ETag,Location
Content-Length:0
Date:Mon, 15 May 2017 12:46:14 GMT
Location: //my API
Server:Microsoft-IIS/8.5
X-Powered-By:ASP.NET

Maybe your safari is an old version that works according to the old recommendations that every custom header must be prefixed with X-
see this link:
enter link description here

Related

Cordova API call works fine in Android and Postman but returns null in iOS

API request in Cordova app works fine in Android device but the same code returns data as null when running in iOS device.
If I copy the request from Safari inspector as a cURL and hit it in postman, it works fine.
I see that request Content-type is set as application/json, but the response content-type is text/html
response also returns another header 'content-encoding' as 'gzip'
Can anyone help me fix this please ?

Angular 1.6, $http.post not working in Firefox

I'm trying to make a simple Angular "$http.post" request to a basic registration REST API, but when I check the network tab (developer tools) in Firefox, the POST request is missing.
$http.post('http://example.com/api/user/userregistration', $scope.userInfo).then(function successCallback(response){
console.log(response.data.object, status);
$scope.processing = false;
$scope.processed = true;
},function errorCallback(response){
console.log(response.config, response.data);
});
I do see a HTTP OPTIONS pre-flight request with 200 OK response, but no subsequent POST request seems to work.
I also tried making a Jquery Ajax POST request to the same API but to no avail.
The same Angular code works perfectly fine in Chrome & Safari (OSX Sierra).
I have attached the screenshot of the OPTIONS request which is returning 200 OK but the subsequent POST request is missing (no errors in console)
Please help troubleshoot the above and suggest if I'm missing something obvious.
Ok found the problem and solved it.
The problem:
The Firefox browser installed in my OSX machine was not showing any error, hence I was unable to troubleshoot.
Checked the same POST request from a Firefox in Windows machine, fortunately saw an error saying:
Cross-origin request blocked. (Reason: invalid token "multipart/form-data" in CORS header "Access-Control-Allow-Headers")
The above error means Firefox does not treat "multipart/form-data" as a valid entry in "Access-Control-Allow-Headers" HTTP response header. (However, Chrome & Safari seem cool about it!)
The Solution:
Removed "multipart/form-data" from the "Access-Control-Allow-Headers" HTTP response header and Voila it worked in Firefox as well!

Ionic/AngularJS HTTP Response Header is null on Safari/Chrome/Desktop Browsers

I'm trying to get the header of a HTTP-Response.
I can get the header on the iPhone without any problems.
But my browser just gets null. Using the Safari Developer Console I can see, that there is the header I want to get. Somehow I can't get the header in AngularJS.
$http.post("/login", loginData)
.then(function(response){
console.log(response.headers("X-AUTH-TOKEN"));
})

trouble changing request headers in Firefox with AngularJS

My backend requires the 'Content-Type' request header to be exactly 'application/json'. This is a CORS request and everything works fine in Chrome. The exact header, from developer tools network tab source:
Content-Type: application/json
I set this in AngularJS with $http.default.headers.post and it works fine in Chrome. However it doesn't work in Firefox. Firefox sends this instead:
Content-Type: application/json; charset=UTF-8
I tried to change headers by:
settings $http.default.headers (for .post, .common)
setting custom headers for one request
using an $http interceptor
All of those methods work well in Chrome, but not in Firefox. The request contains data.
If I remove the 'Content-Type' header all together, it still is sent, but then it is:
Content-Type: text/plain; charset=UTF-8
(this happens in both Chrome and Firefox).
This leads me to think that the browser forces the header :)
How can I circumvent this in Firefox?
Firefox has charset=UTF-8 hard-coded for string payloads.
You may however send a Blob instead:
var r = new XMLHttpRequest();
r.open("POST", ...);
r.send(new Blob(
[JSON.stringify({a:1})],
{type:"application/json"}
));
This also works perfectly fine with the angular $http XHR wrapper:
$http({
method: "POST",
url: "/echo/json",
headers: {
"Content-Type": "application/json"
},
data: new Blob([JSON.stringify({
a: 1
})])
});
Fiddle

Angularjs: Passing along a token using $resource?

I am trying to pass along a token using headers with my $resource requests. Normally you can do the following
$http.defaults.headers.common
in the .config, but I am unaware of these when the application first bootstraps so I thought i would do the following... But its currently not passing my headers..
Currently the token is hard coded but once i have confirmed it working then it will come from a injected service that holds the token.
var resource = $resource('http://localhost:port/todos/:id', {
port:":3001",
id:'#id'
}, {
get: {
method: "GET",
headers: {
"Accept": "application/stuffs;version=3",
"Authorization": "Token token='xxxxxxxxx '"
}
},
update: {method: 'PUT'}
});
return resource;
If i check fiddler I don't see the accept or authorization headers in my request.
I do see the message in fiddler but none of the headers that i was expecting.
Am I missing something here?
Any ideas?
Thanks
First, there is nothing wrong with your client side code. It should work fine if you're not doing cross origin request (CORS - xhr request to a different host / port than what's serving your script). Here is a working non CORS plkr example with your code - you can verify that your custom headers are being sent: http://plnkr.co/edit/cEBGjvYBpXv1q1D323IL?p=preview
If you have to do a cross origin request you have to make sure that you're both using a browser that supports CORS (IE >= 10, latest Chrome or Firefox) and that your server code responds properly to the CORS preflight OPTION request. This article explains it pretty good: http://www.html5rocks.com/en/tutorials/cors/
I've created another plnkr example and got this working by setting up a server that responds the following (http://plnkr.co/edit/zJVhqJVSnApXGzGGxcN9?p=preview)
First - the preflight OPTION request
Request URL:http://localhost:8080/todos
Request Method:OPTIONS
Server response
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,PUT
Access-Control-Allow-Headers: Authorization
Content-Length: 0
Next the "real" request
Request URL:http://localhost:8080/todos
Request Method:GET
Response (notice that access-control-allow headers are here also):
HTTP/1.1 200 OK
Content-Type: application/x-json; charset=UTF-8
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,PUT
Access-Control-Allow-Headers: Authorization
Content-Length: 13
Response body:
{"test":"OK"}
I looked into this by looking through the Angular code on GitHub. What I found out is that as of Angular 1.1.2, you can specify headers exactly as you have in your question. You can't specify headers in any version prior to 1.1.2.
As rGil suggested, make sure you are using the latest version of ngResource. It's very easy to upgrade Angular to 1.1.5, but not upgrade ngResource. In fact, I've done the very same thing with ngResource.
If you want be 100% sure, look for the following code inside ngResource (assuming you have the unminified code). This code loops over each property passed into your action (method and headers in your example) and copies them into an object (httpConfig). httpConfig is then passed into $http.
forEach(action, function(value, key) {
if (key != 'params' && key != 'isArray' ) {
httpConfig[key] = copy(value);
}
});
If you're missing this loop, you have an old version of ngResource.

Resources