I am using angular JS to send some data to nodejs server.
When I use, curl, I get back the data I send (correct result):
curl -d '{"MyKey":"My Value"}' -H "Content-Type: application/json" 'http://127.0.0.1:3000/s?table=register_rings&uid=1'
> {"MyKey":"My Value"}
However, when I use angularjs service, error occures.
.factory('RegisterRingsService', function($http, $q) {
// send POST request with data and alert received
function send(data, uid) {
$http({
method: 'POST',
url: 'http://127.0.0.1:3000/s?table=register_rings&uid=1',
data: '{"MyKey":"My Value"}',
headers: { "Content-Type": "application/json", "Access-Control-Allow-Origin":"*"},
responseType: 'json'
}).success(function(data, status, headers, config) {
alert('success', data, status);
}).error(function(data, status, headers, config) {
alert('error' + JSON.stringify(data) + JSON.stringify(status));
}).catch(function(error){
alert('catch' + JSON.stringify(error));
});
}
return {send : send};
})
The error is following:
{"data":null,"status":0,"config":{"method":"POST","transformRequest":[null],"transformResponse":[null],"url":"http://127.0.0.1:3000/s?table=register_rings","data":"{\"MyKey\":\"My Value\"}","headers":{"Content-Type":"application/json","Access-Control-Allow-Origin":"*","Accept":"application/json, text/plain, */*"},"responseType":"json"},"statusText":""}
I suspect that I should insert CORS headers, but I am not sure how to do that.
Any help would be appreciated
The problem is how you are transmitting the data over to server. This is because jQuery and Angular serialize the data differently.
By default, jQuery transmits data using Content-Type: x-www-form-urlencoded and the familiar foo=bar&baz=moe serialization. AngularJS, however, transmits data using Content-Type: application/json and { "foo": "bar", "baz": "moe" } JSON serialization, which unfortunately some Web server languages — notably PHP — do not unserialize natively.
To workaround this AngularJS developers provided hooks into the $http service to let us impose x-www-form-urlencoded.
$http({
method :'POST',
url:'...',
data: data, // pass in data as strings
headers :{'Content-Type':'application/x-www-form-urlencoded'} // set the headers so angular passing info as form data (not request payload)
});
Please read this post for a working solution:
http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/
Related
angularjs $http.post is refusing to use my Content-Type
I am working with a contractor - their team are making server-side APIs while I'm putting together a javascript application using angularjs. They insist on making the api only allow calls with application/x-www-form-urlencoded calls, so I'm trying to figure out how to use $http to make a urlencoded call, and running into problems. All the instruction pages I'm finding seem focused on older versions of angularjs.
I try using the below code:
$scope.makeApiCall = function( ){
var apiData = {
"key1" : "value1",
"key2" : "value2"
};
var apiConfig = {
"headers" : {
"Content-Type" : "application/x-www-form-urlencoded;charset=utf-8;"
}
};
return $http.post('/Plugins/apiCall', apiData, apiConfig)
.then(function(response){
$scope.data=response.data;
});
};
But when I make the call, instead of using the Content-Type I provided, the developer tools report that it uses Content-Type: text/html; charset=utf-8
How do I get my $http.post to send the right Content-Type?
How to POST content as application/x-www-form-urlencoded
Use the $httpParamSerializerJQLike service to transform the data:
.controller(function($http, $httpParamSerializerJQLike) {
//...
$http({
url: myUrl,
method: 'POST',
data: $httpParamSerializerJQLike(myData),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
});
For more information, see
AngularJS $httpParamSerializerJQLike Service API Reference
Stackoverflow -- URL-encoding variables using only AngularJS services
What is type of data angular sending? I use laravel + angular. I`m trying, but this script return 405 error. Method not allowed.
.controller('adminCtrl', function( $scope, $http ){
$scope.collection = [];
$scope.newData = [];
$scope.newrecord = function() {
$scope.collection.push($scope.newData);
$http({
url: '/newrecord',
method: "POST",
data: $.param($scope.collection),
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
}).success(function(data){
console.log(data);
})
}
})
You are getting 405 - Method not Allowed because the server you are sending your request does not have POST it the white list of methods allowed to be used to perform requests to that given API.
It's not an angularJS issue, it's a server configuration issue.
$http sends data as json.
You do not need to serialize params using "$.param", data is plain javascript object, which is send to your REST endpoint.
So attach just "$scope.collection) and do not set Content Type manually, it is json by default.
POST can be send also with convenience method.
$http.post('/someUrl', data, config).then(successCallback, errorCallback);
I am able to send emails successfully using GMail's API with no issues. The receiver gets the email after a few seconds, but the app doesn't get a response from GMail (i.e., threadid, id, etc...) described here.
I'm running this on a mobile device via IonicFramework w/c uses angularJS by the way. What could be wrong?
$http({
method: 'POST',
url: 'https://www.googleapis.com/upload/gmail/v1/users/me/messages/send?uploadType=multipart',
headers: {
'Authorization':'Bearer '+ access_token,
'Content-Type': 'multipart/mixed; boundary="foo_bar_baz"'
},
data: emailStr
})
.success(function(data, status, headers, config){
console.log(data);
})
.error(function(data, status, headers, config){
console.log(data);
});
emailStr contains the base64-encoded message.
This is how the request details look like:
Request URL: https://www.googleapis.com/upload/gmail/v1/users/me/messages/send?uploadType=multipart
Request Headers
Accept:application/json, text/plain, */*
Authorization:Bearer <<token here>>
Content-Type:multipart/mixed; boundary="foo_bar_baz"
Origin:file://
User-Agent: <<User agent data>>
Query String Parameters
uploadType:multipart
Request Payload
--foo_bar_baz
Content-Type: application/json; charset="UTF-8"
{"raw":"<<encoded string>>"}
--foo_bar_baz--
Here is the call I make the Parse.com's API to login the user:
var deferred = $q.defer();
$http({
method: "GET",
url: "https://api.parse.com/1/login",
headers: {
"X-Parse-Application-Id": PARSE_CREDENTIALS.APP_ID,
"X-Parse-REST-API-Key": PARSE_CREDENTIALS.REST_API_KEY,
"Content-Type": "application/json"
},
data: {
"username": credentials.username.toLowerCase(),
"password": credentials.password
}
}).success(function(data) {
deferred.resolve(data);
}).error(function() {
deferred.reject("error")
});
return deferred.promise;
When I trigger this Angular service method, I get the following error in my console:
XMLHttpRequest cannot load https://api.parse.com/1/login. Request header field Access-Control-Allow-Headers is not allowed by Access-Control-Allow-Headers.
I'm not sure how to resolve this. Here are the current contents of the common headers object for my Angular app:
Object {Accept: "application/json, text/plain, */*", Access-Control-Allow-Headers: "origin, content-type, accept"}
I implement the $http service almost exactly the same for my custom classes without error. The only difference is the URL. Can anyone provide an answer as to why I am getting this error?
EDIT: From this other question, I've gathered that the header field error is the result of the header in the Parse.com response, not in my request. But I am not sure how to proceed now.
EDIT 2: Attached is an image of the HTTP request and response headers that I get when I ping the login API URL.
Are you setting these headers for all http requests somewhere in your angular app?
I'm not sure how to resolve this. Here are the current contents of the
common headers object for my Angular app:
Object {Accept: "application/json, text/plain, */*", Access-Control-Allow-Headers: "origin,
These should come from the server only (response headers), so if they are being set somewhere in the request, then the server would error due to extra headers it was not expecting.
So here is the relevant part of the documentation from AngularJS about using the $http dependency.
params – {Object.<string|Object>} – Map of strings or objects which will be turned to ?key1=value1&key2=value2 after the url. If the value is not a string, it will be JSONified.
data – {string|Object} – Data to be sent as the request message data.
So I conflated params with data. Parse.com expects an URL-parameterized string of the username and password. My confusion was partly because I thought there was a mismatch of request and response headers. But this was not the case.
var deferred = $q.defer();
$http({
url: "https://api.parse.com/1/login",
headers: {
"X-Parse-Application-Id": PARSE_CREDENTIALS.APP_ID,
"X-Parse-REST-API-Key": PARSE_CREDENTIALS.REST_API_KEY,
"Content-Type": "application/json; charset=utf-8"
},
params: {
"username": credentials.username.toLowerCase(),
"password": credentials.password
}
}).success(function(data, status, headers, config) {
deferred.resolve(data);
}).error(function(data, status, headers, config) {
deferred.reject("error")
});
Additional note: For any Angular developers out there who are concerned about the security of user credentials, you will need to set up SSL for your site to ensure that this data does not fall victim to a man-in-the-middle attack. For information on how to set up SSL with Parse.com, read this article.
If, you do not want to pay for an SSL certificate as DigiCert prescribes (e.g. this app is not for customers, but for internal purposes), check out this article for information on how to create your own SSL certificate and save yourself +$100/year.
Currently I'm working with paypal API and flowing with this document make your first call.
When I sent a request through angular $http to paypal, I got a Status Code 415. It's seems like I missed something, does anyone can help me? :)
here is my code
$http({
url: 'https://api.sandbox.paypal.com/v1/oauth2/token',
method: 'POST',
headers: {'Content-Type': 'application/json',
'auth-token': 'EOJ2S-Z6OoN_le_KS1d75wsZ6y0SFdVsY9183IvxFyZp EClusMEUk8e9ihI7ZdVLF5cZ6y0SFdVsY9183IvxFyZp',
'Accept-Language': 'en_US'
},
data: { 'grant_type': 'client_credentials' }
}).success(function (data, status, headers, config) {
console.log(data)
}).error(function (data, status, headers, config) {
console.log(data)
});
Referring to the Paypal doc
Tip: If you're using Windows, we recommend you make cURL calls using a
Bash shell. If you're not using cURL calls, set the content-type to
application/x-www-form-urlencoded for this request.
Try set the content_type as application/x-www-form-urlencoded