When I do a POST request using my angular app to my laravel api I get an error bad request 400 , however GET requests work normally, also I do POST requests using POSTMAN and it works , here is my code :
$http.get('http://localhost/laravel/datingApp/jobapi/public/api/user/users');
this get request works, this post request doesn't (data is an js object {'email': 'value','password': 'value'}) :
$http({
url: 'http://localhost/laravel/datingApp/jobapi/public/api/user/login',
method: 'POST',
contentType: "application/json",
data: data
}).success(function(data) {
console.log(data);
});
also I tried doing that just regular way: $http.post('blabla'); but it doesn't work either :(
edit: sorry didn't include error:
angular.js:12011 POST
http://localhost/laravel/datingApp/jobapi/public/api/user/login 400 (Bad Request)
(anonymous function) # angular.js:12011
sendReq # angular.js:11776
serverRequest # angular.js:11571
processQueue # angular.js:16383
(anonymous function) # angular.js:16399
$eval # angular.js:17682
$digest # angular.js:17495
$apply # angular.js:17790
(anonymous function) # angular.js:25890
dispatch # jquery.min.js:3
q.handle # jquery.min.js:3
That was a stupid error, but thanks to #piscator I have found it, Laravel by default returns 400 when validation rules are not met , So my input was wrong all the time that is the reason I got 400.
If the post request is working via postman, it seems that when your angular app does an post request it gets stuck due to browser CORS policy.
You need to have a access-control-allow-origin present in the header of the response for the post requests to works.
Related
I am using angular JS to send some data to Payment Gateway.
Syntax for curl to send data as per documentation is:
curl https://www.mybank.co.uk/3dsecure
-H "Content-type: application/x-www-form-urlencoded"
-X POST
-d 'TermUrl=https://www.yourmerchantsite.co.uk/3DSecureConfirmation&PaReq=value-of-oneTime3DsToken&MD=merchantdatavalue'
However when I am doing it in Angular :
$http({
method: 'POST',
url: 'url',
headers: {'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'text/html'
},
data: $.param({TermUrl: obj.TermUrl ,Pareq: obj.Pareq }),
})
I am getting error
Possibly unhandled rejection: {"data":"<html><head><title>400 Bad
Request</title></head><body><h1>Bad Request</h1></body>
</html>","status":400,"config":
{"method":"POST","transformRequest":[null],"transformResponse":
[null],"jsonpCallbackParam":"callback","url":"payement gatway
url","headers":{"Content-Type":"application/x-www-form-urlencoded",
"Accept":"text/html,application/xhtml+xml"},"data":"TermUrl=url&Pare
q=value"},"statusText":"Bad Request","xhrStatus":"complete"}
Kindly suggest how to proceed with this one ?
First of all, you are experiencing a 400 Bad Request (https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400) and not a 404 Not Found.
It usually means that you are not sending the right data to the server and the API is expecting some specific parameters (from the body usually).
Check the API, look at every parameter required from it - their types and how they should be sent (body param? query string? etc...).
You can use your browser network tab or tools like Postman to see what you are actually sending to the server and if it matches what the server is expecting you to send.
Check out 3D Secure's API reference, you should get back a detailed error code beside the http status code:
https://developer.paysafe.com/en/3d-secure/api/#/introduction/error-summary/common-errors
It should be easily debuggable.
I am using Angular2 RC5 (core, http, etc) and trying to connect to a CORS enabled Node.js server. My application is fresh generated from Angular-CLI (version: "1.0.0-beta.11-webpack.2").
// src/app/app.component.ts
...
ngOnInit () {
const headers: Headers = new Headers();
headers.append('Accept', 'application/json');
headers.append('Content-Type', 'application/json');
headers.append('Access-Control-Allow-Origin', '*');
const options = new RequestOptions({
headers: headers
});
this.http.get('http://localhost:9000/api/v1/users', options)
.map((res: Response) => res.json())
.subscribe(users => console.log(users));
}
...
When the application starts, the OnInit hook got called, I got an error in the console. Here is the error message that I got.
EXCEPTION: TypeError: Cannot read property 'toString' of null
browser_adapter.js:84EXCEPTION: TypeError: Cannot read property 'toString' of nullBrowserDomAdapter.logError # browser_adapter.js:84BrowserDomAdapter.logGroup # browser_adapter.js:94ExceptionHandler.call # exception_handler.js:65(anonymous function) # application_ref.js:267ZoneDelegate.invoke # zone.js:323onInvoke # ng_zone_impl.js:53ZoneDelegate.invoke # zone.js:322Zone.run # zone.js:216(anonymous function) # zone.js:571ZoneDelegate.invokeTask # zone.js:356onInvokeTask # ng_zone_impl.js:44ZoneDelegate.invokeTask # zone.js:355Zone.runTask # zone.js:256drainMicroTaskQueue # zone.js:474
zone.js:461 Unhandled Promise rejection: Cannot read property 'toString' of null ; Zone: <root> ; Task: Promise.then ; Value: TypeError: Cannot read property 'toString' of null(…)consoleError # zone.js:461_loop_1 # zone.js:490drainMicroTaskQueue # zone.js:494
zone.js:463 Error: Uncaught (in promise): TypeError: Cannot read property 'toString' of null(…)
If I drop off the options and header completely, I got CORS error but response status 200 from the server. (I guess that If I can pass the correct Header, it should work. )
this.http.get('http://localhost:9000/api/v1/users')
.map((res: Response) => res.json())
.subscribe(users => console.log(users));
Here is the error from the console
XMLHttpRequest cannot load http://localhost:4000/api/v1/users. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access.
browser_adapter.js:93EXCEPTION: Response with status: 0 for URL: null
browser_adapter.js:84EXCEPTION: Response with status: 0 for URL: nullBrowserDomAdapter.logError # browser_adapter.js:84BrowserDomAdapter.logGroup # browser_adapter.js:94ExceptionHandler.call # exception_handler.js:65next # application_ref.js:348schedulerFn # async.js:89SafeSubscriber.__tryOrUnsub # Subscriber.js:225SafeSubscriber.next # Subscriber.js:174Subscriber._next # Subscriber.js:124Subscriber.next # Subscriber.js:88Subject._finalNext # Subject.js:128Subject._next # Subject.js:120Subject.next # Subject.js:77EventEmitter.emit # async.js:77onHandleError # ng_zone_impl.js:74ZoneDelegate.handleError # zone.js:327Zone.runTask # zone.js:259ZoneTask.invoke # zone.js:423
Subscriber.js:229Uncaught Response with status: 0 for URL: null
Can someone help, please? thanks.
I am a newbie so bear with me please, but as far as I am concerned the Access-Control-Allow-Origin header should be returned by the backend Node.js server. CORS on server side is disabled by default due to security.
Use the following question to help you with implementation: How to allow CORS?
Your problem is caused by a bug introduced in rc5. The XHRBackend for Http was modified to convert the body of any request into a string. It looks at the Content-Type header and attempts to call the appropriate conversion method.
In your code above, you are setting the Content-Type header to application/json which causes the XHRBackend to try to convert it into a string. However, since you're making a GET request, body is null, so this exception is being thrown.
In your case, just remove the Content-Type header, and everything should work fine.
It is written about here:
https://github.com/angular/angular/issues/10612
To resolve
EXCEPTION: TypeError: Cannot read property 'toString' of null
you need to set body to ''
headers.append('body', '');
How to post JSON data to web-service via AngularJS
here is the code snippet
.controller('MessagePostCtrl', function($scope, $http) {
$scope.postMessage = function() {
var msg = document.getElementById('message').value;
var msgdata = {
message : msg
};
var res = $http.post('http://<domain-name>/messenger/api/posts/savePost',msgdata);
res.success(function(data, status, headers, config) {
console.log(data);
});
}
})
OPTIONS http:///messenger/api/posts/savePost
ionic.bundle.js:16185(anonymous function) ionic.bundle.js:16185
sendReq ionic.bundle.js:15979 serverRequest ionic.bundle.js:15712
wrappedCallback ionic.bundle.js:19197 wrappedCallback
ionic.bundle.js:19197(anonymous function) ionic.bundle.js:19283
Scope.$eval ionic.bundle.js:20326 Scope.$digest ionic.bundle.js:20138
Scope.$apply ionic.bundle.js:20430(anonymous function)
ionic.bundle.js:43025(anonymous function) ionic.bundle.js:10478
forEach ionic.bundle.js:7950 eventHandler ionic.bundle.js:10477
triggerMouseEvent ionic.bundle.js:2648 tapClick ionic.bundle.js:2637
tapMouseUp ionic.bundle.js:2707
XMLHttpRequest cannot load
http:///messenger/api/posts/savePost. Invalid HTTP
status code 404
But when I remove the msgdata from $http.post method, everything is working fine.
Can anyone tell me where the issue is or else guide me how to send JSON data to web-service
Thanks for the help
**Edited:
The Issue was with the CORS, Im using codeigniter REST Controller for web-services.
Modified the headers. If anyone has the same issue add the below header in the construct
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method");
if ( "OPTIONS" === $_SERVER['REQUEST_METHOD'] ) {
die();
}
Thanks to Linial for the break-through, telling me where the issue is.**
Okay,
You mixed up couple of things:
First as I can see your request has changed from POST to OPTIONS.
Why?
You are performing Cross-site HTTP requests ( CORS ), which means that your WebApp and your backend API are not in the same domain.
What happens live is that the request is being preflighted.
Preflighted request: by Mozilla MDN:
It uses methods other than GET, HEAD or POST. Also, if POST is used
to send request data with a Content-Type other than
application/x-www-form-urlencoded, multipart/form-data, or text/plain,
e.g. if the POST request sends an XML payload to the server using
application/xml or text/xml, then the request is preflighted.
Which means, any request beside GET, HEAD or POST will be change to OPTIONS
AND: Also POST if used to send data with Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain
I now understand, but what to do? I have to make POST request!
You don't have many options, since CORS is defined on the server.
But on the client you could do so (Example):
change the encode type in angular like so:
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
OR
Set your server to approve CORS like so:
Access-Control-Allow-Headers: Content-Type \\ This will allow you to set content type header in the client.
Access-Control-Allow-Methods: GET, POST, OPTIONS \\ This will allow you to send GET POST and OPTIONS, which is necessary because of preflighted requests.
Access-Control-Allow-Origin: * \\ This will allow anyone to perform CORS requests.
Good Luck!
I am trying to create an angularjs application as a cbssports plugin.
They provide a RESTful API.
The following is my $http request:
$http.get(basePath + 'league/owners?access_token=' + cbssportsTokens['access_token'] + '&response_format=JSON')
.success(function(data) {
return data;
});
That is wrapped up in a factory and used in a controller. As far as I can tell this is getting executed correctly. When I look at the chrome developer tools I can see the following error on my request from the console:
OPTIONS http://api.cbssports.com/fantasy/league/owners?access_token=U2FsdGVkX18Hyd0…J9DrpO7C-OXQQNXGMh0ej0iXVfPf5DkQwkLwSpCqGhipd6HogV_gZ&response_format=JSON angular.js:8560
(anonymous function) angular.js:8560
sendReq angular.js:8354
$http.serverRequest angular.js:8087
wrappedCallback angular.js:11572
wrappedCallback angular.js:11572
(anonymous function) angular.js:11658
Scope.$eval angular.js:12701
Scope.$digest angular.js:12513
Scope.$apply angular.js:12805
done angular.js:8378
completeRequest angular.js:8592
xhr.onreadystatechange
XMLHttpRequest cannot load http://api.cbssports.com/fantasy/league/owners?access_token=U2FsdGVkX18xBod…oQWvjDVSbpZCOVsoIKeVXKRSYdo6dBbIE0rgMWTkWhmgPUTyr_xnS&response_format=JSON. The 'Access-Control-Allow-Origin' header has a value 'https://www.cbssports.com' that is not equal to the supplied origin. Origin 'http://xx.xx.xx.xx:9001' is therefore not allowed access. ?access_token=U2FsdGVkX18xBodWEOfeqys5X4aDpghYrE22FGljlJd_TtKRHlWh4LHWFwVxay95BbAWvn4te1foQWvjDVSbp…:1
When I click the link that it said it couldn't load, it takes me to a new page with the expected output!! So clearly CORS shouldn't be an issue here from the server.
I have read many different issues with CORS about changing the headers. The follow is how I have set it up:
$httpProvider.defaults.headers.common['Access-Control-Allow-Origin'] = '*';
$httpProvider.defaults.headers.common['Access-Control-Allow-Headers'] = 'Origin';
Any advice would be greatly appreciated, also my first post to SO, so please let me know if more info would help.
So I didn't exactly get it to work. But I found a sort of workaround.
function _get(url) {
return $resource(basePath + url, {
access_token: cbssportsTokens['access_token'],
response_format: 'JSON',
callback: 'JSON_CALLBACK'
}, {
get: {
method: 'JSONP'
}
});
}
I went ahead and used a JSONP request instead of a GET, the cbs server seems to be happier with that.
I'm using $http to post some data to my data base.
Here is the documentation of the database.
I use it on my terminal and it works.
Here's the error message I got from Safari's console:
1)Failed to load resource: Request header field 0 is not allowed by Access-Control-Allow-Headers. (seems to be sensed by the database)
2)XMLHttpRequest cannot load https://beta-api.mongohq.com/mongo/MyDId/myDatabse/collections/myCollection/documents. Request header field 0 is not allowed by Access-Control-Allow-Headers.
Here's my code:
factory.sendUrlTag = function(data){
d = '{"document" : {"url_URL":"53738eef9256a31f4fdf6bf8","tag_Tag":"537375fc9256a31f4fdf6bf3"} }'
return $http({
url: 'https://beta-api.mongohq.com/mongo/MyDId/myDatabse/collections/myCollection/documents',
method: "POST",
data: d,
headers: [
{'Access-Control-Allow-Origin':'*'},
{'Access-Control-Allow-Headers':'Origin, X-Requested-With, Content-Type, Accept'},
{'Content-Type': 'application/json'},
{'Authorization' : 'api-key MyKey'}
]
})
}
return factory;
};
I didn't have " {'Access-Control-Allow-Origin':'*'},
{'Access-Control-Allow-Headers':'Origin, X-Requested-With, Content-Type, Accept'}," before, but I did some research after I got the error and added these. But it's still not working.
I do $http.get() in my app to the same database and it works.
This thing is driving me nuts....
Please help!
Thank you all! :)
Access-Control-Allow-Origin and friends are response headers, not request headers. It wouldn't make sense if Bob was responsible for granting Bob permission to Alice's system.
The server (https://beta-api.mongohq.com/mongo/MyDId/myDatabse/collections/myCollection/documents) has to send them, not the client.
Since you are making a cross-origin POST request, the server also needs to be able to respond to a pre-flight OPTIONS request.
I found some way maybe able to get around the issue:
Use this and here to get around the cross origin origin issue.
And this to get around the localhost
It may work.
Another relative post.