Making http POST request in Angular 2 - angularjs

I want to make the following POST request in Angular 2.
http://gearman.local.eviry.com/info
with body as the following
{"gearman_servers" :[{
"name" : "server 1",
"addr" : "192.168.1.115"
},
{
"name" : "Server 2",
"addr" : "192.0.1.126"
}
]}
I have made sure that this works outside Angular 2. (Using POSTMAN)
I have also made sure that there is CORS enabled.
Following is my angular code
var url = 'http://gearman.local.eviry.com' +
'/info';
var GEARMAN_DATA = {"gearman_servers" :[{
"name" : "server 1",
"addr" : "192.168.1.115"
},
{
"name" : "Server 2",
"addr" : "192.0.1.126"
}]};
let body = JSON.stringify(GEARMAN_DATA);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
this.http.post(url, body, options)
.map(res => res.json())
.subscribe(
data => {console.log(data);},
err => this.logError(err),
() => console.log('Fetching complete for Server Metrics')
);
logError(err:Response){
console.log("some error");
console.log(err);
}
However, doing this gives me an error
XMLHttpRequest cannot load http://gearman.local.eviry.com/info. Invalid HTTP status code 405
Also, when I print out the error inside the logError function, I get the following:
http://grab.by/O7s8
It is difficult to make out what is wrong with the request.
Request Headers are as shown
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:content-type
Access-Control-Request-Method:POST
Cache-Control:no-cache
Connection:keep-alive
Host:gearman.local.eviry.com
Origin:http://evil.com/
Pragma:no-cache
Referer:http://localhost:3000/gearman-ui/job-queue
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.155 Safari/537.36
X-FirePHP:0.4.4
X-FirePHP-Version:0.4.4
X-Wf-Max-Combined-Size:262144
Response headers are as shown
Allow:POST
Cache-Control:no-cache
Connection:Keep-Alive
Content-Length:4519
Content-Type:text/html; charset=UTF-8
Date:Mon, 15 Feb 2016 08:32:54 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.2.24 (Unix) mod_ssl/2.2.24 OpenSSL/1.0.1e-fips
If anybody uses POSTMAN, I have the following code which works. I have to implement the same using angular.(Note that you wont be able to access http://gearman.local.eviry.com)
https://www.getpostman.com/collections/f14ecaf29ffd52a54534

I made a try with your request (see this plunkr: http://plnkr.co/edit/6sbNYgIlCMNLkyyRerEk?p=preview) and appears that the reponse of your preflighted request isn't correct:
XMLHttpRequest cannot load http://gearman.local.eviry.com/info. Response for preflight is invalid (redirect)
After having a look at the reponse of this one, I have the following:
General
Request URL:http://gearman.local.eviry.com/info
Request Method:OPTIONS
Status Code:302 Found
Remote Address:49.212.179.100:80
Response Headers
Connection:close
Content-Length:293
Content-Type:text/html; charset=iso-8859-1
Date:Mon, 15 Feb 2016 08:12:44 GMT
Location:https://gearman.local.eviry.com/info
Server:Apache
Request Headers
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8,fr-FR;q=0.6,fr;q=0.4
Access-Control-Request-Headers:content-type
Access-Control-Request-Method:POST
Cache-Control:no-cache
Connection:keep-alive
Host:gearman.local.eviry.com
Origin:http://run.plnkr.co
Pragma:no-cache
Referer:http://run.plnkr.co/IwOhToeVuXn1o1a4/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36
The 302 status code for this request is the problem I think. Moreover I didn't see any CORS headers in its response...

Related

Why do I get a CORS error with React, axios and Flask?

I know that this has been asked so many times, but none of the answers I've found seems to work. My app is React frontend and Flask backend via an api. I have just switched to axios from the usual await fetch and it keeps throwing CORS errors:
Access to XMLHttpRequest at 'http://127.0.0.1:5050/api/user/register' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
My code is thus:
const config = {
headers: {
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/json" ,
},
}
const customFetch = axios.create({
baseURL: 'http://127.0.0.1:5050',
});
export const registerUser = createAsyncThunk(
'user/registerUser',
async (user, thunkAPI) => {
try {
const resp=await customFetch.post('/api/user/register', user, config);
return resp.data ;
}catch (error) {
return thunkAPI.rejectWithValue(error.response.data.msg);
}
}
);
My server has
CORS(app)
now also added:
#app.after_request
def add_security_headers(resp):
resp.headers['Access-Control-Allow-Origin']='*'
resp.headers['Access-Control-Allow-Methods']='GET, POST, PUT, OPTIONS'
resp.headers["Access-Control-Allow-Headers"]="Access-Control-Request-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Access-Control-Allow-Origin, Origin, X-Requested-With, Content-Type, Accept"
return resp
and in any case it works ok for a standard:
await fetch(`${api_host}/api/user/register`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
data here ...
}),
});
its driving me mad, any clues? Thanks
UPDATE
Just in case there isn't enough info here are the request and response headers:
General
Request URL: http://127.0.0.1:5050/api/user/register
Request Method: POST
Status Code: 500
Referrer Policy: strict-origin-when-cross-origin
Request
POST /api/user/register HTTP/1.1
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;q=0.9,en-US;q=0.8
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 110
Content-Type: application/json
DNT: 1
Host: 127.0.0.1:5050
Origin: http://localhost:3000
Referer: http://localhost:3000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.27
sec-ch-ua: "Microsoft Edge";v="105", " Not;A Brand";v="99", "Chromium";v="105"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Response
HTTP/1.0 500 INTERNAL SERVER ERROR
Content-Type: text/html; charset=utf-8
X-XSS-Protection: 0
Connection: close
Server: Werkzeug/2.0.0 Python/3.8.10
Date: Fri, 09 Sep 2022 17:52:09 GMT
Once again, any suggestions gratefully received.
I added the following headers server-side, and it seems to have solved it.
I dont know why it stopped working when I switched axios. With standard asyc call it was fine.
resp.headers['Access-Control-Allow-Origin']='*'
resp.headers['Access-Control-Allow-Methods']='GET, POST, PUT, OPTIONS'
resp.headers["Access-Control-Allow-Headers"]="Access-Control-Request-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Access-Control-Allow-Origin, Origin, X-Requested-With, Content-Type, Accept"

How to send CORS request from React?

I have problem with sending CORS request with token in header.
Fetch code:
fetchApi() {
fetch('http://some-link.com',
{
headers: {
'Accept': 'application/json',
'auth-token': 'xxxxxxxxx'
},
method: "GET"
}).then(response => response.json())
.then(function(response){
this.setState({hits:response});
}).catch(function(error) { console.log(error); });
console.log(this.state.hits);
};
Console log:
Access to fetch at 'http://some-link.com' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field auth-token is not allowed by Access-Control-Allow-Headers in preflight response.
Network request log:
General
Request URL: http://some-link.com
Request Method: OPTIONS
Status Code: 200 OK
Remote Address: some_ip:80
Referrer Policy: no-referrer-when-downgrade
Response Headers
Access-Control-Allow-Headers: origin, x-requested-with, content-type, auth_token
Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin: *
Cache-Control: no-cache, private
Connection: Keep-Alive
Content-Length: 8
Content-Type: application/json
Date: Tue, 13 Nov 2018 13:30:35 GMT
Keep-Alive: timeout=5, max=100
Server: Apache/2.4.10 (Debian)
Request Headers
Provisional headers are shown
Access-Control-Request-Headers: auth-token
Access-Control-Request-Method: GET
Origin: http://localhost:3000
Referer: http://localhost:3000/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36
Any ideas what might be wrong?
You have to change the server settings to allow the header "auth-token".
Once you do this, your request will work.
You are currently allowing "auth_token", not "auth-token".
Alternatively, change the header name in the frontend like so:
headers: {
'Accept': 'application/json',
'auth_token': 'xxxxxxxxx'
}

AngularJS - Can't pass a header on a $http request

I'm trying to do requests to a RestAPI coded with Codeigniter 3. Access-Control-Allow-Origin and Access-Control-Allow-Headers are set to "*". The API has been successfully tested on Postman.
I'm coding a Web App using AngularJS, and trying to do requests to that API. The following code works properly:
api_service.getUsers = function() {
return $http({
method : 'GET',
url : url + '?dd-api-key=' + api_key
});
}
As this other code functions well too:
api_service.getUsers = function() {
return $http.get(url + '?dd-api-key=' + api_key);
}
But I need to send the API key as a header and not in the URL. So I wrote the function this way:
api_service.getUsers = function() {
return $http({
method: 'GET',
url: url,
headers: {
'accept': undefined,
'dd-api-key': api_key
}
});
}
That code doesn't work. Google Chrome console displays me this:
OPTIONS http://www.myweb.com/api/v1/users
XMLHttpRequest cannot load http://www.myweb.com/api/v1/users. Invalid HTTP status code 403
And at the network tab it shows that the request uses a method type 'OPTIONS', not a 'GET' method.
The Response Headers are:
Access-Control-Allow-Headers:*
Access-Control-Allow-Methods:PUT, GET, POST, DELETE, OPTIONS
Access-Control-Allow-Origin:*
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:keep-alive
Content-Language:es-ES
Content-Length:45
Content-Type:application/json; charset=utf-8
Date:Wed, 25 Mar 2015 01:45:09 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Pragma:no-cache
Server:nginx/1.6.2
And the Request Headers are:
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:es-ES,es;q=0.8,en;q=0.6
Access-Control-Request-Headers:dd-api-key
Access-Control-Request-Method:GET
Connection:keep-alive
Host:www.myweb.com
Origin:http://127.0.0.1:55652
Referer:http://127.0.0.1:55652/index.html
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36
Excuse me if my english is not correct.
Many thanks.
you should add header with this:
$http.defaults.headers.common.dd-api-key = api_key;
You can add it in some config as global.

AngularJS $http seems to not respond correctly when I am using CORS

I have an AngularJS application. It sends out requests to another server for data and so there's an OPTIONS request goes out with every $HTTP call.
When I check with fiddler there are two calls. The Options that always returns a 200 OK and then the data call.
However when I check the $HTTP it seems that it's getting the first request ( the options request ) and not getting the second request the one with real data.
Can someone point me in the right direction with this?
Here's one example of the code that is not responding correctly:
.factory('isUsernameAvailable', function (appConstant, $q, $http) {
return function (username) {
var deferred = $q.defer();
// if (!angular.isDefined(username) || username == null || username == "" || username.length < 6 ) return deferred.resolve();
var url = appConstant.baseUrl + '/api/user/existsByName';
$http({
url: url,
method: "PUT",
data: {
userName: username
}
}).then(function (data) {
// Found the user, therefore not unique.
deferred.reject("User name is taken");
}, function (data) {
// User not found, therefore unique!
deferred.resolve();
});
return deferred.promise;
}
})
I expect it to be returning as success or failure depending on if it finds the username. But in this case it always responds as a fail/error.
Here are the requests being made:
OPTIONS http://localhost:3048/api/user/existsByName HTTP/1.1
Host: localhost:3048
Connection: keep-alive
Access-Control-Request-Method: PUT
Origin: http://localhost:2757
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Access-Control-Request-Headers: accept, authorization, content-type
Accept: */*
Referer: http://localhost:2757/Auth/register
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
giving:
HTTP/1.1 200 OK
Server: Microsoft-IIS/8.0
Access-Control-Allow-Origin: http://localhost:2757
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: PUT
Access-Control-Allow-Headers: content-type
X-SourceFiles: =?UTF-8?B?QzpcR1xhYmlsaXRlc3Qtc2VydmVyXFdlYlJvbGVcYXBpXHVzZXJcZXhpc3RzQnlOYW1l?=
X-Powered-By: ASP.NET
Date: Mon, 12 Jan 2015 17:52:12 GMT
Content-Length: 0
Then:
PUT http://localhost:3048/api/user/existsByName HTTP/1.1
Host: localhost:3048
Connection: keep-alive
Content-Length: 35
Accept: application/json, text/plain, */*
Origin: http://localhost:2757
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Authorization: null
Content-Type: application/json;charset=UTF-8
Referer: http://localhost:2757/Auth/register
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
{"userName":"abdddcdefgg#live.com"}
giving:
HTTP/1.1 404 Not Found
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/8.0
Access-Control-Allow-Origin: http://localhost:2757
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: X-Custom-Header
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcR1xhYmlsaXRlc3Qtc2VydmVyXFdlYlJvbGVcYXBpXHVzZXJcZXhpc3RzQnlOYW1l?=
X-Powered-By: ASP.NET
Date: Mon, 12 Jan 2015 17:52:12 GMT
Content-Length: 0
The problem is even if the second request returns a 200 when I debug the success and error functions it still goes to the error function all of the time.
You should use JSONP to do cross domain JSON calls. Look at the documentation here: https://docs.angularjs.org/api/ng/service/$http#jsonp. Also, your referring page and the response from the OPTIONS request must have the appropriate CORS headers set or else the browser will refuse to send the request here are the header settings that I use.
Access-Control-Allow-Headers:Content-Type, Authorization, Content-Length, X-Requested-With, Accept, x-csrf-token, origin
Access-Control-Allow-Methods:GET,PUT,POST,DELETE,OPTIONS
Access-Control-Allow-Origin:*
To call $http.jsonp with a PUT request, you would set up a configuration such as
var config = {
method: 'POST',
data: { test: 'test' }
};
and then pass that into the $http.jsonp call
$http.jsonp('http://example.com', config);
Here is more documentation https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS and http://en.wikipedia.org/wiki/JSONP

Why does a cross-domain angularjs $http.post request fail when a XMLHttpRequest succeeds?

I am trying to exercise the Trello API with an application key and token from an angular (version 1.0.5) webapp. The server seems correctly configured to handle CORS. A test request with http://test-cors.org from enable cors works as expected.
When I do a post request in one of my angular controllers:
$http.post(url).success(function(data) {
$scope.server_resp = data;
});
I get a Request header field Content-Type is not allowed by Access-Control-Allow-Headers error. (Even though, as you see below, the Access-Control-Allow-Origin is set to '*'). Why is this header added and can it be removed?
XMLHttpRequest
When I make the same request using raw XMLHttpRequest, it succeeds. Here are the headers for the XMLHttpRequest:
Request Method:POST
Status Code:200 OK
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:0
Host:api.trello.com
Origin:http://192.168.0.125:9000
Referer:http://192.168.0.125:9000/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22
Response
Access-Control-Allow-Methods:GET, PUT, POST, DELETE
Access-Control-Allow-Origin:*
Cache-Control:max-age=0, must-revalidate, no-cache, no-store
Content-Length:563
Content-Type:application/json
Date:Mon, 18 Mar 2013 02:49:37 GMT
Expires:Thu, 01 Jan 1970 00:00:00
X-Powered-By:Express
X-Server-Time:1363574977568
Angular $http.post
Here are the headers for the angular initiated request. Note that the browser made a pre-flight OPTIONS request:
Request Method:OPTIONS
Status Code:200 OK
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, origin, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:api.trello.com
Origin:http://192.168.0.125:9000
Referer:http://192.168.0.125:9000/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22
Response
Access-Control-Allow-Methods:GET, PUT, POST, DELETE
Access-Control-Allow-Origin:*
Content-Length:0
Content-Type:text/html; charset=utf-8
Date:Mon, 18 Mar 2013 02:51:00 GMT
X-Powered-By:Express
Is there a way to configure angular's request headers to allow the above $http.post() code to work?
The 'content-type' header is not accepted by the server and is added by default for Angular $http POST request (see $http doc). You can try to remove it from your $http config. Inject $httpProvider in your controller, then this might work:
delete $httpProvider.defaults.headers.post['Content-type']
You might have to try with 'content-type' also, I'm not sure of the case to use.
Add the headers param to the $http and you'll be fine.
var config = {
method: 'POST',
url: 'your url',
headers: {
'Content-Type': undefined
},
data: {
"channel": "#fun-and-game",
"username": $scope.question.title,
"text": $scope.question.text,
"icon_emoji": ":ghost:"
},
};
$http(config).success(function(data) {
$scope.server_resp = data;
}).error(function(response) {
});
for more info, check angularjs $http docs
As per this angular pull request, CORS can be made to work by deleting X-Requested-With which causes a pre-flight OPTIONS request:
App.config(['$httpProvider', function($httpProvider) {
delete $httpProvider.defaults.headers.common["X-Requested-With"];
}
Note that I have not tried this personally, but a co-worker had to deltete the header to make his CORS request work.
I just ran into a similar issue and the problem was that I was getting the url wrong. I was posting to 1/cards/actions/createCard because I missread the docs. I got an access-control related error even though headers etc. look right. Posting to 1/cards created a card, which is what I wanted.
This worked for me
$http({
method : "POST",
url : url,
data : $.param({key: 'value', key2 : 'value'}),
headers : { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' }
})
To avoid this issue, create a function in the server side to catch the 'OPTIONS' and just return true. Some thing as follows.
/**
* #url OPTIONS /
*/
public function options()
{
return;
}

Resources