AngularJS Ignoring $http.default.headers - angularjs

Angular v1.3.5
I'm trying to pass serialized data to my API. It requires the Content-Type header to be application/x-www-form-urlencoded; charset=UTF-8;
For POST, I've set this up as follows in my .run:
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8;";
This works great for POST. However, for PUT doing the same is completely ignored.
$http.defaults.headers.put["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8;";
I even tried putting this in the request. The Content-Type was still ignored.
$http({
method : 'PUT',
url : SMARTWORX_CONFIGS.APIURL + 'users/' + service.profile.id + '.json',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8;'
},
data : {
user : profile
}
})
I've been forced to solve this by using an interceptor and adding the headers to the config object there. It's quite a hack, but it works.
Am I doing something wrong here?

After beating my head on the wall some more, I discovered the problem - of my own making.
My app is using tokens for authentication; so, I have an interceptor to inject the token into the headers when needed. I made a mistake with this.
It looked like :
config.headers = config.header || {};
config.headers['X-AUTH-TOKEN'] = result;
It SHOULD have been written like:
config.headers = config.headers || {};
config.headers['X-AUTH-TOKEN'] = result;
Basically, I was blowing out all previous headers.

Related

Can't include header in `$http` angular

I got a token from backend which I saved it in $sessionStorage and I need to include that along with $http request that I call. I tried include it directly but when I checked it from backend, it's not there.
function _selectGender($sessionStorage, gender) {
return $http({
method: 'POST',
url: config.apiURL + '/auth/gender',
headers: {
'Authorization': $sessionStorage.token
},
data: {
gender: gender
}
}).then(updateCompleted).catch(updateFailed);
}
I also tried with interceptor which it's not working as well.
requestInterceptor.inject = ['$sessionStorage'];
function requestInterceptor($sessionStorage){
return {
'request': function(config){
if ($sessionStorage.token) config.headers['authorization'] = $sessionStorage.token;
return config;
}
}
}
Shoot me some idea how to tackle this. :D
Edit#1: It's likely possible to be preflight error
It's actually because of OPTIONS headers, seem like $http will send a pre-request before browser send an actual request to backend. You need to handle that from the backend. Thanks #Nitish Kumar's comment.
Read more about cors
How to handle OPTIONS

Symfony + AngularJS 401 unauthorized error after Get method

I have some concerns(marigolds) with my method GET when I send my request. I have received an error 401 and I am disconnected from the application, knowing that the token which I obtain in the console is very valid when I test on postman. I does not really understand(include) why that does not work I have to add some things or I have pain make something.
var list = function(){
var mytoken = window.localStorage.getItem('token');
return $http({
method : 'GET',
url : apiEndpoint.url + '/list',
withCredentials : true,
headers : {Authorization : 'Bearer ' + mytoken}
}).then(function(res) {
console.log(res.data);
});
};
If somebody could me helped please, thank you :)
I think that she uses of the angularJS in her project, while RequestOptions is a class which we find that in Angular 2. That's why the import does not work
It must be added in the conf of apache:
SetEnvIf Authorization. + HTTP_AUTHORIZATION = $ 0
It should work for your case :)
Please check it like below:
let headers = new Headers();
headers.append('Authorization', 'Bearer ' + YourToken);
let options = new RequestOptions({ headers: headers });
this.http.get('YourUrl', options)
This should work

AngularJS 1.3 to 1.5 transformRequest broke, solution for my specific situation?

Long story short. I am really not an AngularJS guru. Our site upgraded from 1.3 to 1.5. This one thing is breaking.
We used to inject an HTTP header via transformRequest in a factory named 'api':
.factory('api', function($resource) {
function add_auth_header(data, headersGetter) {
var headers = headersGetter();
headers['Authorization'] = ('Basic ' + btoa(data.username +
':' + data.password));
}
// defining the endpoints.
return {
auth: $resource('/api/v1/auth/', {}, {
login: {method: 'POST', transformRequest: add_auth_header},
logout: {method: 'DELETE'},
}),
Later on in the same file, this is called like so:
.service('auth', function($cookies, $rootScope, api) {
this.user = null;
this.login = function(credentials) {
var log = api.auth.login(credentials);
log.$promise.then(function(data){
// on good username and password
this.user = data;
});
As you can see, it calls api.auth.login with the credentials. I have verified that the transform request is being called, the headers are being fetched properly by headersGetter(), and that hanging the headers[] object no longer changes it like it used to in 1.3. Fiddler verifies that the request no longer has an Authorization header in it like it did in 1.3, and the Django server that gets the request also agrees.
I've read in a few places that the transformRequest functionality 'broke' in 1.4, but those posts have always been in the context of making an $http request, not providing an api service through a factory, and haven't made much sense to an AngularJS newb like me. I have no idea where I would start changing how Authorization is injected.
Can anyone point me the right way?
If anyone else is still facing this, the change was under breaking changes in the changelog for 1.4.
I feel the fix speaks for itself. Note that the function add_auth_header is not invoked but rather is passed.
.factory('api', function($resource) {
function add_auth_header(data) {
// as per HTTP authentication spec [1], credentials must be
// encoded in base64. Lets use window.btoa [2]
return 'Basic ' + btoa(data.data.username + ':' + data.data.password);
}
// defining the endpoints.
return {
auth: $resource('/api/v1/auth/', {}, {
login: {method: 'POST', headers: { 'Authorization': add_auth_header }},
logout: {method: 'DELETE'},
}),

Issue sending JSON in POST request to Play App

i am working on a project using Play Framework 2.4 using a simple Java template, as in many documentation i have seen, i just wrote a simple controller with my business methods and put the necessary paths on my route's file.
Now i am writing a client in Angular.js to invoke the logic written in the play app. It had work perfectly with GET methods, but when i try to do a POST from angular using the next lines:
$http({
method: 'POST',
url : rootURL + '/user/company',
data : {id : '123456' , name: 'xxxxxx'}
});
I receive a 404 Error. After several hours of forums searching, i found that the Play App is expecting application/x-www-form-urlencoded in the request content-type header.
So i modify my Angular call to the following:
$http({
method: 'POST',
url : rootURL + '/user/company',
data : {id : '123456' , name: 'xxxxx'},
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj){
var str = [];
for(var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
}
})
};
And the POST works perfectly on this way, but i wonder, is there any way so i can make a POST request to my play app where the content-type is set to application/json? How can achieve this?
UPDATE
Here is my controller code:
public class MyController extends Controller {
public Result myAction(){
//do funny stuffs
}
}
And my route file has the following
POST /path/action controllers.MyController.myAction()
Have you added #BodyParser.Of(BodyParser.Json.class) in your action method?
Also when you are doing POST to a different domain, first check you request to see if it's a POST, I don't know about AngularJS, but with Polymer, it sent a OPTION first during ajax POST to different domain, and I met very similar issue (wrong content type and 404) which is resolved by implementing an OPTION on server which accept POST.
To Fix that, you need to manually implement an OPTION, here's what to do:
First, In your routes file, add an entry to accept OPTION
OPTIONS /*url controllers.Application.optionCheck(url)
Then implement the optionCheck method which accept everything
public Result optionCheck(String url){
response().setHeader("Access-Control-Allow-Origin", "*");
response().setHeader("Access-Control-Allow-Methods", "POST");
response().setHeader("Access-Control-Allow-Headers", "accept, origin, Content-type, x-json, x-prototype-version, x-requested-with");
return ok();
}
And that's it

ngResource Dynamic Header

I'm trying to make a request to an API service that has a dynamic 'authorization' header.
var domain = "http://www.externalapi.com",
actions = {
'login': {
method: 'POST'
},
'objects': {
method: 'GET',
headers: {
'Authorization': Request.getAuthHeader()
}
}
};
var requests = $resource(domain, {}, actions);
requests.objects();
Request is a service I've written that has a method that builds the auth header based on the api requirements, the has it returns is correct.
When looking at the request to domain, however, I see not 'Authorization' header...
I've also tried passing in a static string, still no header.
So the issue was my versions.
After updating Angular to 1.2.0rc1 I left my ngResource module at 1.0.8.
After updating both to 1.2.0rc1 (I assume 1.1.2 would work as well) I was able to assign headers from the actions object of $resource.

Resources