As part of a project I'm working on, we need to send a cross domain request.
I have the following call:
$http({
url: 'http://192.168.1.1/API/Login',
method: "POST",
data: {
password: $scope.pass
},
withCredentials: true,
cached: false,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json',
}
}).then(function successCallback(response) {
}, function errorCallback(response) {
});
When I send the request to the non-origin server, I get the following response (from Wireshark):
POST /API/Login HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Accept: application/json
Accept-Language: en-US,en;q=0.7,he;q=0.3
Origin: http://myserver.com
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586
Host: 192.168.1.1
Content-Length: 21
Connection: Keep-Alive
{"password":"1234"}
HTTP/1.1 200 OK
Date: Sun, 19 Jun 2016 21:07:52 GMT
Server: Some server (UNIX)
Set-Cookie: Session=308333957
Accept-Ranges: bytes
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://myserver.com
Content-type: application/json
Content-Length: 152
{"key":"abcdefg","name":"Joe","session":"308333957"}
It works perfectly fine in Chrome and FireFox but on Edge it has a CORS error:
Origin http://myserver.com not found in Access-Control-Allow-Origin header.
Btw, when the login credentials are wrong and the server does not return the 'Set-Cookie' it works fine!!!
Thought that by using 'withCredentials=true' I'll allow setting cookies in a cross domain request but it didn't help (on Edge only).
Any ideas?
Any chance there's a bug in Edge? I couldn't find anything open.
Thanks
Related
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'
}
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
I have an issue processing responses from a server to a PUT request (same happens with POST). Starts with the following CORS pre-flight request.
Request:
OPTIONS /open/Patient/1 HTTP/1.1
Host: remoteserver.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: PUT
Origin: http://myclient
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36
Access-Control-Request-Headers: accept, content-type
Accept: */*
DNT: 1
Referer: http://myclient/patient/2JT
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Response:
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 0
Date: Sat, 13 Sep 2014 16:58:28 GMT
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Content-Location, Location
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: accept, content-type
Access-Control-Request-Method: GET, POST, PUT, DELETE
Server: Name of remote server
Then the actual request:
PUT /open/Patient/1 HTTP/1.1
Host: remoteserver.com
Connection: keep-alive
Content-Length: 775
Pragma: no-cache
Cache-Control: no-cache
Accept: application/json+fhir, application/json, text/plain, */*
Origin: http://myclient
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36
Content-Type: application/json+fhir
DNT: 1
Referer: http://myclient/patient/2JT
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
The response is not processed by AngularJS, instead it reports the following error:
net::ERR_METHOD_NOT_SUPPORTED
The body of the response is empty, and the status is "0". Thing is, if I set a break point in the Chrome debugger, after stepping through the code, I DO get a successful response. Here's what I get in the response:
HTTP/1.1 200 OK
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/json+fhir; charset=UTF-8
Content-Length: 154
Date: Sat, 13 Sep 2014 17:13:35 GMT
Pragma: no-cache
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Content-Location, Location
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Content-Location: http://remoteserver/open/Patient/1/_history/6
Server: Health Intersections FHIR Server
Here's the body of my code that sends the request using $http:
function updateResource(resourceUrl, resource) {
var deferred = $q.defer();
$http.put(resourceUrl, resource)
.success(function (data, status, headers, config) {
var results = {};
results.data = data;
results.headers = headers();
results.status = status;
results.config = config;
deferred.resolve(results);
})
.error(function (data, status) {
var error = { "status": status, "outcome": data };
deferred.reject(error);
});
return deferred.promise;
}
I've resolved this issue working with the developer of the server. Turns out there was an issue with the way the server handled connections. Resolved.
I am using Cordova's inappbrowser and integrating Google oauth2.0. Once I get the authorization code I make a post request to get my token. NO MATTER what I try I always get a 400 error with "Required Parameter is missing grant_type". I'm encoding uri, I'm setting the right headers but to no avail... can anyone help?
$http({
method: 'POST',
url: 'https://accounts.google.com/o/oauth2/token',
params:{code:authorization_code[0],
client_id:options.client_id,
client_secret:options.client_secret,
redirect_uri:options.redirect_uri,
grant_type:'authorization_code'},
headers:{
'Content-Type':'application/x-www-form-urlencoded',
}
}).success(function(data,status,headers,config){
deferred.resolve(data);
}).error(function(data, status,headers,config){
console.log('data, status, headers,config',data,status,headers,config);
deferred.reject(response.responseJSON);
});
and this is the output from the Chrome dev Console when I try to make the request
Request URL:https://accounts.google.com/o/oauth2/token?client_id=736406995874-oh7o4cmaju3jgprllln97nf0p3pc1f91.apps.googleusercontent.com&client_secret=ysgrIV6mJXxritfXnRcclV_U&code=4%2FnITDK731NhavPePthrVA1eX8LHFC.ojUX9K7DpBYaEnp6UAPFm0HWDS5njgI&grant_type=authorization_code&redirect_uri=http:%2F%2Flocalhost
Request Method:POST
Status Code:400 Bad Request
Request Headers
POST https://accounts.google.com/o/oauth2/token?client_id=xxx-oh7o4cmaju3jgprllln97nf0p3pc1f91.apps.googleusercontent.com&client_secret=xxx&code=4%2FnITDK731NhavPePthrVA1eX8LHFC.ojUX9K7DpBYaEnp6UAPFm0HWDS5njgI&grant_type=authorization_code&redirect_uri=http:%2F%2Flocalhost HTTP/1.1
Accept: application/json, text/plain, /
Origin: file://
testing: testing
User-Agent: Mozilla/5.0 (Linux; Android 4.4.2; SCH-I535 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36
Query String Parameters
client_id=xxx-oh7o4cmaju3jgprllln97nf0p3pc1f91.apps.googleusercontent.com&client_secret=xxx&code=4%2FnITDK731NhavPePthrVA1eX8LHFC.ojUX9K7DpBYaEnp6UAPFm0HWDS5njgI&grant_type=authorization_code&redirect_uri=http:%2F%2Flocalhost
Response Headers
HTTP/1.1 400 Bad Request
Pragma: no-cache
Date: Mon, 14 Jul 2014 06:35:22 GMT
Content-Encoding: gzip
X-Content-Type-Options: nosniff
Server: GSE
X-Frame-Options: SAMEORIGIN
Content-Type: application/json
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Transfer-Encoding: chunked
Alternate-Protocol: 443:quic
X-XSS-Protection: 1; mode=block
Expires: Fri, 01 Jan 1990 00:00:00 GMT
Wrong post request. The params property is used to set any additional request parameters to be appended to the URL query string. The params property is a JavaScript object with one property per request parameter to add.
Here for your reference.
You just need to send data/params in serialized (for angular use $httpParamSerializer)
$http({
method: 'POST',
url: 'https://accounts.google.com/o/oauth2/token',
params:$httpParamSerializer({code:authorization_code[0],
client_id:options.client_id,
client_secret:options.client_secret,
redirect_uri:options.redirect_uri,
grant_type:'authorization_code'}),
headers:{
'Content-Type':'application/x-www-form-urlencoded',
}
}).success(function(data,status,headers,config){
deferred.resolve(data);
}).error(function(data, status,headers,config){
console.log('data, status, headers,config',data,status,headers,config);
deferred.reject(response.responseJSON);
});
I'm trying to configure a simple service with Angular.js and Couchdb
var App = angular.module('myapp', ['ngResource'], function(){});
App.factory('products', ['$resource', function($resource) {
var Products = $resource(
'http://localhost\\:5984/products/_all_docs',
{},
{ all: { method: 'GET'} }
);
return {
all: function() {
return Products.all();
}
};
}]);
When I call products.all() from my controller always I get
Request headers
OPTIONS /productos/_all_docs HTTP/1.1
Host: localhost:5984
Connection: keep-alive
Access-Control-Request-Method: GET
Pragma: no-cache
Cache-Control: no-cache
Origin: http://localhost:8000
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.56 Safari/537.17
Access-Control-Request-Headers: accept, origin, x-requested-with
Accept: */*
DNT: 1
Referer: http://localhost:8000/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: es-419,es;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Response headers
HTTP/1.1 405 Method Not Allowed
Server: CouchDB/1.2.1 (Erlang OTP/R14B04)
Date: Tue, 29 Jan 2013 22:15:31 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 69
Cache-Control: must-revalidate
Allow: GET,HEAD,POST
Request URL:http://localhost:5984/productos/_all_docs
Request Method:OPTIONS
Status Code:405 Method Not Allowed
I can not imagine why it sends an OPTIONS method when I haven't declared that!
The OPTIONS method comes from doing a cross origin request. See Why am I getting an OPTIONS request instead of a GET request?. Even though both the host and the request is to localhost, the ports are different (5984, 8000). See Same origin host, different ports in JS.