$http headers gets added under Access-Control-Request-Headers - angularjs

Whenever I try to add custom Request headers to my $http request the headers does not show up in the Request, instead its comes under Access-Control-Request-Headers like Access-Control-Request-Headers:accept, testHeader
See below the output in chrome's network tab:
Request Headers:
OPTIONS /v/xyx/abc/query?q=SELECT%20duration%20FROM%20TimeTable HTTP/1.1
Host: example.com
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://localhost
User-Agent: XXXXXXXX Chrome XXXXXXX
Access-Control-Request-Headers: accept, testHeader
Accept: */*
Referer: http://localhost/test/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Whereas,I am expecting something like:
Request Headers:
OPTIONS /v/xyx/abc/query?q=SELECT%20duration%20FROM%20TimeTable HTTP/1.1
Host: example.com
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://localhost
User-Agent: XXXXXXXX Chrome XXXXXXX
Accept: application/json
testHeader: zdhfguwe87fg8378287efijb8
Referer: http://localhost/test/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
How can I prevent this from happening and show the headers under Request header?
See the config of the $http service in Angularjs that I've followed:
//***TRIED BOTH OF THESE:
//***TRY#1 $http.get(url, {headers:{"Accept": "application/json", "testHeader": "zdhfguwe87fg8378287efijb8"}}).then(.......
//***TRY#2
$http({
method: 'GET',
url: url,
headers: {
"Accept": "application/json",
"testHeader": "zdhfguwe87fg8378287efijb8"
}
})
.then(
function(){
//success
console.log(arguments);
}, function(){
//fail
console.log(arguments);
});

This is expected behavior as part of the CORS-preflight, which is an OPTIONS request. Once this request succeeds, the actual GET request will be fired by the browser with the custom headers, because the server accepted them.
Only a limited set of headers is approved by default for CORS requests, therefore to add others (including your custom header), the CORS-preflight request needs to ask the server for permission with the Access-Control-Request-Headers HTTP header.
See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests

It has bloody taken my 3 hours to search for the fxxking answer.
Basically it is simple, just let stupid server accept the custom header.
What I have done were adding these to .htaccess
<IfModule mod_headers.c>
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type, x-custom-header-here"
</IfModule>
Now it allows server(API) to accept ajax request from everywhere with most methods and whatever your custom header is or headers are.
it will erase error msg of 'Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.'
fxxking all these stupid rule makers!

Related

Random occurrence with preflight response missing allow headers

I've got quite random occurrence with this common error:
OPTIONS https://api.cloudfunctions.net/api/graphql 404
Access to fetch at 'https://api.cloudfunctions.net/api/graphql' from origin 'https://website.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
What I have is a graphql endpoint with apollo server deployed on Google Cloud Functions and a react client. At some points the client will throw the error on browser but if I try refresh or send the request again 2 or 3 times later it will work.
The preflight request headers being sent:
:authority: api.cloudfunctions.net
:method: OPTIONS
:path: /api/graphql
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9,id;q=0.8,ms;q=0.7
access-control-request-headers: content-type
access-control-request-method: POST
origin: https://website.com
referer: https://website.com/
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/79.0.3945.88 Safari/537.36
Expected response
access-control-allow-credentials: true
access-control-allow-headers: content-type
access-control-allow-methods: POST,OPTIONS
access-control-allow-origin: https://website.com
alt-svc: quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000
content-length: 0
content-type: text/html
date: Wed, 08 Jan 2020 00:38:16 GMT
function-execution-id: 84et92k6mvd9
server: Google Frontend
status: 200
vary: Origin, Access-Control-Request-Headers
x-cloud-trace-context: 95d25375171148a66bc629cc41a79d05
x-powered-by: Express
Random failed response
alt-svc: quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000
cache-control: private
content-encoding: gzip
content-length: 140
content-security-policy: default-src 'none'
content-type: text/html; charset=utf-8
date: Wed, 08 Jan 2020 00:38:05 GMT
function-execution-id: 84etgky3im1k
server: Google Frontend
status: 404
x-cloud-trace-context: 77040d2c72304cad0d645480b6814f7f;o=1
x-content-type-options: nosniff
x-powered-by: Express
Looking at the failed response above kinda make sense that it's missing the access-control-allow-* headers compared to success one, but again I am not sure how that happened.
Here's my cors config:
const corsConfig = {
origin: ['https://website.com', 'http://localhost:3000'],
methods: ['POST', 'OPTIONS'],
credentials: true,
optionsSuccessStatus: 200,
}
const app = express()
app
.use(cors(corsConfig))
.use(...)
...
apolloServer.applyMiddleware({ app, cors: corsConfig })
Based on few suggestions around I have tried different setup but still sometimes the error happens:
set cors: false in applyMiddleware
remove cors
repeat cors as shown above
add app.options('*', cors()) as per doc says
All and all it happens like 1 in 10, sometimes on first request after the user open the site the other times after the user browsing around the site for a while.
I think there might be other middleware that messes up your cors settings.
You can try use a different path for your graphql endpoint, and apply cors only to that path.
apolloServer.applyMiddleware({ app, path: '/graphql', cors: corsConfig });
Alternatively, you can try the express cors middleware and disable the cors from apollo server
I used the apollo-server-cloud-functions package to solve this problem. Just follow the instructions here (https://github.com/apollographql/apollo-server/tree/master/packages/apollo-server-cloud-functions) but instead of using exports.handler = server.createHandler() swap it out for your own function, like this:
exports.api = functions.https.onRequest(
server.createHandler({
cors: {
origin: true,
credentials: true
}
})
);
That solved it for me!

Response for preflight has invalid HTTP status code 405 on Angular Js1 and Webapi 2

Error:
OPTIONS http://localhost:8080//api/home/GetText 405 (Method Not Allowed)
http://localhost:8080//api/home/GetText. Response for preflight has invalid HTTP status code 405
angular.js:14362 Error: Error getting home/GetText data from the database!
Headers:
Response Headers:
Access-Control-Allow-Credentials:false
Access-Control-Allow-Headers:gid,Origin, X-Requested-With, Content-Type, Accept, Authorization
Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin:*
Allow:GET
Content-Length:76
Content-Type:application/json; charset=utf-8
Date:Fri, 28 Jul 2017 10:30:06 GMT
Server:Microsoft-IIS/10.0
X-Powered-By:ASP.NET
Request Headers:
Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:authorization,gid
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
Host:localhost:8080
Origin:http://evil.com/
Pragma:no-cache
Referer:http://localhost:1852/
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
Please note that i am using Angular Js as client and Webapi for server side. I am performing xhr request through $resource service.
This is because your back-end API doesn't support OPTIONS request for your routes (specifically /api/home/GetText this route). AngularJS typically checks CORS requests by issuing OPTIONS requests prior to making actual content requests.
You need to enable support for OPTIONS requests at your back-end, and return appropriate headers + good HTTP status (200-299) from there.
protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod != "OPTIONS") return;
HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "gid, filename, Origin, X - Requested - With, Content - Type, Accept, Authorization");
HttpContext.Current.Response.AddHeader("Access-Control-Expose-Headers", "X-filename");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
This fixed the above issue.
it Means that your're tryng to call a method from FRONT END TO BACK END with the WRONG HTTP VERBS (so for example PUT INSTEAD of POST)
double check it

Angular js get request with headers- showing CORS error

In my angular controller code my http get method not working with header but the same request working in postman
$http({
method: 'GET',
url: 'http://localhost:8080/api/profiles',
headers: {
'Authorization': 'Bearer 78954642-sf25-4sd6-sdf2-99582369d5af',
'Content-Type':'text/plain'
}
}).then(function(success) {
console.log(success);
}, function(error) {
});
Showing following error
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://quotebuilder' is therefore not allowed access. The response had HTTP status code 401.
My request header
OPTIONS /api/profiles HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: GET
Origin: http://quotebuilder
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Access-Control-Request-Headers: authorization
Accept: */*
Referer: http://quotebuilder/login
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: en-US,en;q=0.8
What is wrong here ? please help me to resolve the issue
Your should make CORS disabled in your server side to make this work. A resource makes a cross-origin HTTP request when it requests a resource from a different domain, or port than the one which the first resource itself serves see dtails here. If you are using spring or other server side web frameworks you need to disable that from there.

How to enable Angular $http redirect on CORS

I have a node/express aplication with CORS enabled
When I do POST /login to my app does a redirect to /failure or /success
but always a i get a
XMLHttpRequest cannot load http://exampledomain.com/login. The request was redirected to 'http://exampledomain.com/success', which is disallowed for cross-origin requests that require preflight.
the $http do two requests to the server
OPTIONS request
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: http://otherdomain.com
Vary: Origin
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET,PUT,POST,PATCH,DELETE
Access-Control-Allow-Headers: accept, content-type
Connection: keep-alive
Options response
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: http://otherdomain.com
Vary: Origin
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET,PUT,POST,PATCH,DELETE
Access-Control-Allow-Headers: accept, content-type
Connection: keep-alive
POST request
POST /admin/login HTTP/1.1
Host: exampledomain.com
Connection: keep-alive
Content-Length: 43
Accept: application/json, text/plain, */*
Origin: http://otherdomain.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2267.0 Safari/537.36
Content-Type: application/json;charset=UTF-8
Referer: http://otherdomain.com
Accept-Encoding: gzip, deflate
Accept-Language: es-419,es;q=0.8
POST response
HTTP/1.1 302 Moved Temporarily
Vary: X-HTTP-Method-Override, Origin, Accept
Access-Control-Allow-Origin: http://otherdomain.com
Access-Control-Allow-Credentials: true
Location: /success
Content-Type: text/plain; charset=utf-8
Content-Length: 45
set-cookie: cookie-data; Path=/; HttpOnly
Connection: keep-alive
I think the headers are correct but something is missing about the Location header. Can help me with this
I'm doing the request with $http like follows
$http.defaults.useXDomain = true;
$http.post('http://exampledomain/login', {
username: 'user',
password: 'pass'
}).success(...).error(...)
but the success is never called
CORS is not enabled for http://exampledomain.com, thus no requests can be made to it. In fact the browser does a preflight check and since it fails the requests are not actually sent to the server at all.
The only way to change this is to enable CORS on the server for your domain.

AngularJS not sending request after CORS preflight response

Using AngularJS to call RESTFUL APIs.
When using Chrome browser on IOS, the CORS preflight request's (OPTIONS request's) Accept header gets set to */*,image/webp. The response comes back fine, but the actual GET request never gets sent. As you can see in the response, the Content-Type header gets set to image/webp, which I suspect is causing the problem in AngularJS from moving forward with the GET request.
Is my assumption correct? If so, is the solution to force the server to set the Content-Type to something else ?
Full request headers:
OPTIONS http://www.example.com:8080/resourceABC HTTP/1.1
Host: www.example.com:8080
Connection: keep-alive
Access-Control-Request-Headers: accept, authorization, origin
Access-Control-Request-Method: GET
Origin: http://www.example.com
Accept: */*,image/webp
Referer: http://www.example.com/
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 8_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) CriOS/38.0.2125.67 Mobile/12B411 Safari/600.1.4
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Full response headers:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Allow: GET,OPTIONS,HEAD
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS
Access-Control-Allow-Headers: X-HTTP-Method-Override, Content-Type, x-requested-with, authorization, accept
Access-Control-Max-Age: 3600
Content-Type: image/webp
Content-Length: 0
Date: Wed, 29 Oct 2014 19:26:37 GMT
Hy.
I just had the same thing here accessing a REST-Service on a different domain from AngularJS-Service.
Examining the request-headers sent to my REST-Service to see if I do allow everything that is requested from the client lead mit to the following:
Setting 'Access-Control-Allow-Headers' in a way to make sure it contains all items in 'Access-Control-Request-Headers' solved it for me.
Marc I see that in your 'Access-Control-Request-Headers' the header "origin" is requested but in your "Access-Control-Allow-Headers" it's missing.
Sending the following Response-Headers works in my case (appkey is my internal auth-key in header):
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: *
Access-Control-Allow-Headers: appkey,content-type
Hope this is clear and it helps.
Best regards,
Christian
P.S.: "Access-Control-Allow-Headers: *" did not work in my case
UPDATE:
To allow Form-Submit via POST-Request I had to add 'content-type' to 'Access-Control-Allow-Headers'

Resources