AngularJS $http.post() firing get request instead of post - javascript

i building an API service in angular and laravel, when i firing a GET call to the API everythings work fine, but when i fire POST call the service still use GET method instead of POST.
that is my service:
function LeadsAPI($http,$q,BASE_URL)
{
this.updateLead = function (lead_data) {
var url = BASE_URL+"/leads/update/";
var deferred = $q.defer();
$http.post(url , lead_data).then(function(response){
deferred.resolve(response.data);
});
return deferred.promise;
}
}
i call to this function from a Controller:
LeadsController.$inject = ['$scope', 'LeadsAPI'];
function LeadsController($scope , LeadsAPI)
{
LeadsAPI.updateLead({'lead_id' : res._id, 'the_lead': {'fist_name' : 'asd asd'}}).then(function (res) {
console.log(res);
});
}
i tried pass the parameters as a string ("a=b&c=d...") and added header :
$http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
in the run function at my App module instantiation but yet, i keep getting 405 (Method Not Allowed) error.
any ideas why and how to solve it? thank you very much all! :)

Seems the question is old and unanswered but google led me here. I hope someone will find this answer useful.
I had the same problem. $http was set to POST but server was returning error from GET request.
After checking the headers in a web inspector it shows the browser actually did two requests:
update/ 301 text/html angular.js:11442
update 405 xhr https://test.site/post/update
The first one is the one from $http and the second one is after a redirect.
As you can see the trailing slash URL is redirected to a non trailing one. With this redirect a POST request gets also changed to GET as well.
The solution is to change your request url to not contain trailing slashes:
url: BASE_URL+"/leads/update",

The GET works fine ... good
The POST returns 405 - Method not allowed
It sounds like it is doing a POST and the server you are posting to does not support POST requests to the endpoint in question
Can you please provide more information, such as the HTTP request and response headers when you make a GET request and the same for the POST request
You can access the header information via the NET tab in Firefox's Firebug or in Chrome console

Be sure that your API method is ready to handle a POST request. Maybe Angular is actually firing a POST request, but your method is expecting a GET.
If you are sure Angular is really firing a GET request instead of a POST for some reason, try to explicitly set the HTTP method on the $http object:
$http({
method: 'POST',
url: BASE_URL+"/leads/update/",
data: lead_data
}).then(function (response) {
deferred.resolve(response.data);
});

Related

Angular http GET 405 (Method Not Allowed)

I'm implementing another function in an application (made with angular), I call an API (made with Lumen) and it returns a 405 error whem i tried in local and "XMLHttpRequest cannot load Response for preflight is invalid (redirect)" when i tried on the server. I read about CORS but it's already implemented, I think if it isn't none of others functions would work.
Another thing, if I make the call with Advanced Rest Client it works fine :(
sorry about my english, i don't speak it so much.
function on application
$scope.agencias = [];
$http({
method: 'GET',
//url: 'http://api-beta.grupoaldorf.com.mx/agencias/',
url: 'http://localhost:8000/agencias/',
headers: agenciaMazda.headers
}).then(function successCallback(response) {
$scope.agencias = response.data;
console.log("regreso del http");
console.log($scope.agencias);
}, function errorCallback(response) {
//callback(false);
});
route on web.php
$app->get('agencias','CitasController#agenciasDisponibles');
controller in CitasController.php
public function agenciasDisponibles(Agencia $agencia){
$fabricante = $this->request->header('Aldorf-App');
$disponibles = Agencia::where('fabricante', $fabricante)->where('mostrar', 1)->select(['codigo', 'nombre'])->get();
return $disponibles;
}
Finally i solved it, it was really dumb, i added a slash at the end of the uri xD it had to be "http://localhost:8000/agencias" instead of "http://localhost:8000/agencias/"

How to "get" from NodeJS with AngularJS

I started an AngularJs App and to retrieve some data from database I'm using NodeJS (totally new to me), on the console of NodeJS it works and also typing the URL directly in the browser but when I try to get the information needed using http.get() in AngularJS using the same URL in the browser I get 404 not found.
I figured it would be a cors problem so I added
require('cors') in the nodeJS app and still doesn't work
Can anyone help me with that ?
Am I right making separate apps for Angularjs in front-end and NodeJS in the Backend or should I assemble them in only one application ?
Thank you for your help
This is the AngularJS code:
$scope.keyLoad = function () {
$http.get("localhost:8080/product")
.success(function (response) {
$scope.keys = response;
console.log(response)
})
};
$scope.keyLoad();
I get 404 not found. I figured it would be a cors problem
If it says it is a 404 error then it is a 404 error and not a CORS problem.
Look at your code:
$http.get("localhost:8080/product")
That URL is missing the scheme. It is a relative URL.
You are going to be requesting something like http://example.com/myapp/localhost:8080/product.
Put http:// or https:// in front of it.
You should use $http service.
For example:
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Or
$http.get('/someUrl', config).then(successCallback, errorCallback);

IE8 changing GET request to POST: Angular $http

I am making call to a REST service from my AngularJS app using $http. The issue is whenever I make a GET request from IE8, it gets converted to POST request. Calls with other http methods (POST,PUT) work fine. This happens only with IE8.
Here is my code
```
var request = {method: method, url: url, data: payload};
var promise = $http(request) .then(function (response) {
return response;
});
```
Can someone please help. I have tried sending different types off data payload : null,undefined,empty object, some object. But nothing worked.
I think I have found the solution. We need to send empty string as payload. Or, use $http.get

Preventing HTTP Basic Auth Dialog using AngularJS Interceptors

I'm building an AngularJS (1.2.16) web app with a RESTful API, and I'd like to send 401 Unauthorized responses for requests where authentication information is invalid or not present. When I do so, even with an HTTP interceptor present, I see the browser-presented basic "Authentication Required" dialog when an AJAX request is made via AngularJS. My interceptor runs after that dialog, which is too late to do something useful.
A concrete example:
My backend API returns 401 for /api/things unless an authorization token is present. Nice and simple.
On the AngularJS app side, I've looked at the docs and set up an interceptor like this in the config block:
$httpProvider.interceptors.push(['$q', function ($q) {
return {
'responseError': function (rejection) {
if (rejection.status === 401) {
console.log('Got a 401')
}
return $q.reject(rejection)
}
}
}])
When I load my app, remove the authentication token, and perform an AJAX call to /api/things (to hopefully trigger the above interceptor), I see this:
If I cancel that dialog, I see the console.log output of "Got a 401" that I was hoping to see instead of that dialog:
Clearly, the interceptor is working, but it's intercepting too late!
I see numerous posts on the web regarding authentication with AngularJS in situations just like this, and they all seem to use HTTP interceptors, but none of them mention the basic auth dialog popping up. Some erroneous thoughts I had for its appearance included:
Missing Content-Type: application/json header on the response? Nope, it's there.
Need to return something other than promise rejection? That code always runs after the dialog, no matter what gets returned.
Am I missing some setup step or using the interceptor incorrectly?
Figured it out!
The trick was to send a WWW-Authenticate response header of some value other than Basic. You can then capture the 401 with a basic $http interceptor, or something even more clever like angular-http-auth.
I had this issue together with Spring Boot Security (HTTP basic), and since Angular 1.3 you have to set $httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest'; for the popup not to appear.
For future reference
I've come up with this solution when trying to handle 401 errors.
I didn't have the option to rewrite Basic to x-Basic or anything similar, so I've decided to handle it on client side with Angular.
When initiating a logout, first try making a bad request with a fake user to throw away the currently cached credentials.
I have this function doing the requests (it's using jquery's $.ajax with disabled asynch calls):
function authenticateUser(username, hash) {
var result = false;
var encoded = btoa(username + ':' + hash);
$.ajax({
type: "POST",
beforeSend: function (request) {
request.setRequestHeader("Authorization", 'Basic ' + encoded);
},
url: "user/current",
statusCode: {
401: function () {
result = false;
},
200: function (response) {
result = response;
}
},
async: false
});
return result;
}
So when I try to log a user out, this happens:
//This will send a request with a non-existant user.
//The purpose is to overwrite the cached data with something else
accountServices.authenticateUser('logout','logout');
//Since setting headers.common.Authorization = '' will still send some
//kind of auth data, I've redefined the headers.common object to get
//rid of the Authorization property
$http.defaults.headers.common = {Accept: "application/json, text/plain, */*"};

Adding HTTP Basic Authentication Header to Backbone.js Sync Function Prevents Model from Being Updated on Save()

I'm working on a web application that is powered by a restful API written with Python's CherryPy framework. I started out writing the user interface with a combination of jQuery and server side templates, but eventually switched to Backbone.js because the jQuery was getting out of hand.
Unfortunately, I'm having some problems getting my models to sync with the server. Here's a quick example from my code:
$(function() {
var User = Backbone.Model.extend({
defaults: {
id: null,
username: null,
token: null,
token_expires: null,
created: null
},
url: function() {
return '/api/users';
},
parse: function(response, options) {
console.log(response.id);
console.log(response.username);
console.log(response.token);
console.log(response.created);
return response;
}
});
var u = new User();
u.save({'username':'asdf', 'token':'asdf'}, {
wait: true,
success: function(model, response) {
console.log(model.get('id'));
console.log(model.get('username'));
console.log(model.get('token'));
console.log(model.get('created'));
}
});
});
As you can probably tell, the idea here is to register a new user with the service. When I call u.save();, Backbone does indeed send a POST request to the server. Here are the relevant bits:
Request:
Request URL: http://localhost:8080/api/users
Request Method: POST
Request Body: {"username":"asdf","token":"asdf","id":null,"token_expires":null,"created":null}
Response:
Status Code: HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 109
Response Body: {"username": "asdf", "created": "2013-02-07T13:11:09.811507", "token": null, "id": 14, "token_expires": null}
As you can see, the server successfully processes the request and sends back an id and a value for created. But for some reason, when my code calls console.log(u.id);, I get null, and when my code calls console.log(u.created);, I get undefined.
tl;dr: Why isn't Backbone.js persisting changes to my objects after a call to save()?
Edit:
I've modified the above code so that the model properties are accessed using the get function in a success callback. This should solve any concurrency problems with the original code.
I've also added some console logging in the model's parse function. Oddly enough, each of these is undefined... Does that mean that Backbone.js is failing to parse my response JSON?
Edit 2:
A few days ago, I found out that issue was actually a custom header that I was adding to every request to enable HTTP Basic Authentication. See this answer for details.
This code:
u.save();
console.log(u.id);
console.log(u.username);
console.log(u.token);
console.log(u.created);
Runs immediately... after that there is nothing to run and the queued ajax request begins. The response then comes a bit later and only at that point have the values changed.
It also seems that those properties are not directly on the object, but the asynchronous processing of the save still holds in that you wouldn't get expected results even if you corrected that code to have console.log(u.get("id")) etc.
I figured out the issue, although I'm still at a loss to explain why it's an issue at all. The web app that I'm building has an authentication process that requires an HTTP basic Authentication header to be passed with all requests.
In order to make this work with Backbone, I overrode the Backbone.sync function and changed line 1398 to add the header.
Original Code:
var params = {type: type, dataType: 'json'};
Modified Code:
var params = {
type: type,
dataType: 'json',
headers: {
'Authorization': getAuthHash()
}
};
The function getAuthHash() just returns a Base64 string that represents the appropriate authentication information.
For some reason, the addition of this header makes the sync/save functions fail. If I take it out, everything works as you might expect it to.
The bounty is still open, and I'll happily reward it to anybody who can explain why this is, as well as provide a solution to the problem.
Edit:
It looks like the problem was the way that I was adding the header to the request. There's a nice little JavaScript library available on Github that solves this problem by correctly adding the HTTP Basic Auth header.
i have tested your code, its works fine for me.
See Demo here, jsfiddle.net/yxkUD/
Try to add a custom beforeSend method to the ajax request to add the custom header.
For example:
https://github.com/documentcloud/backbone/blob/master/backbone.js#L1424

Categories

Resources