Allowing cross domain ajax requests with Meteor - javascript

Server side setup
JsonRoutes.setResponseHeaders({
"Cache-Control": "no-store",
"Pragma": "no-cache",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, PUT, POST, DELETE, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization, X-Requested-With"
});
Client side setup
var getRecentPosts = function (token) {
$.ajax({
url: "http://localhost:3000/publications/recentPostsAndComments",
method: "GET",
headers: {
"Authorization": "Bearer " + token,
"Content-Type": "application/json"
},
// contentType: "application/json",
success: function (data, status, xhr) {
debugger
},
error: function (xhr, status, err) {
debugger
}
});
}
I always get caught inside the error callback because of the following error:
XMLHttpRequest cannot load http://localhost:3000/publications/recentPostsAndComments. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:5000' is therefore not allowed
access.
Is there anything noticeable that I am missing here?
Update:
in the network tab, I see one option request that succeeds, but I don't see a GET request that's supposed to be sent.
Remote Address:127.0.0.1:3000
Request URL:http://localhost:3000/publications/recentPostsAndComments
Request Method:OPTIONS
Status Code:200 OK
Response Headers
view source
connection:keep-alive
content-type:text/html; charset=utf-8
date:Sat, 19 Sep 2015 23:53:48 GMT
transfer-encoding:chunked
vary:Accept-Encoding
Request Headers
view source
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8,ko;q=0.6
Access-Control-Request-Headers:accept, authorization, content-type, x-requested-with
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
Host:localhost:3000
Origin:http://localhost:5000
Pragma:no-cache
Referer:http://localhost:5000/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36

This is what I sometimes use and it works great.
//Server Side PHP
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
header('Access-Control-Max-Age: 2000');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X- Requested-With');
?>
As you know, it should be placed before any code....

Related

Javascript Fetch API Cors : Doesen't pass access control check

I am dealing with an external api. I want to post some data so i set a token in the headers to be able to access the api.
I am told that my test origin has been whitelisted http://127.0.0.1:8081/
However i get the following error.
Failed to load
https://external-api.com/api/transactions/ad2d7a69-f723-4798-9fa5-a95a76d65324/document:
Response to preflight request doesn't pass access control check: The
value of the 'Access-Control-Allow-Origin' header in the response must
not be the wildcard '*' when the request's credentials mode is
'include'.
async submitDocument(transationId, token, base64) {
const url = host + "/api/transactions/" + transationId + "/document"
const body = {
"image": base64,
}
let headers = new Headers();
headers.set('Content-type', 'application/json');
headers.set('token', token);
const request = {
method: 'POST',
body: JSON.stringify(body),
mode: 'cors',
headers: headers,
credentials: 'include'
}
const data = await fetch(url, request);
const response = await data.json();
return response;
}
This function call is being made browser side on the following page. http://127.0.0.1:8081/
Response from server
Request URL: https://externalapi.com/api/transactions/f400aaec-3fde-4458-a36e-fe03d550fc00/document
Request Method: OPTIONS
Status Code: 200
Remote Address: 54.194.37.150:443
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Headers: content-type, token
Access-Control-Allow-Methods: GET,POST,PUT,DELETE
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 0
Connection: keep-alive
Content-Length: 0
Date: Fri, 22 Jun 2018 15:29:27 GMT
Server: nginx
Vary: Origin
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Access-Control-Request-Headers: content-type,token
Access-Control-Request-Method: POST
Cache-Control: no-cache
Connection: keep-alive
Host: externalapi.com
Origin: http://127.0.0.1:8081
Pragma: no-cache
Referer: http://127.0.0.1:8081/
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
just read the error message carefully! Your domain must not be whitelistet with '*'.
It has to be 'http://127.0.0.1:8081'. You have to ask external-api.com to recheck it.
In your request you have credentials set in a token header and the Origin of your request is:
Origin: http://127.0.0.1:8081
The request in this case will proceed only if the server answers with:
Access-Control-Allow-Origin: http://127.0.0.1:8081
Otherwise the request is blocked by the browser
Check here for more details:
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Examples_of_access_control_scenarios
In particular the section "Requests with credentials"

Failed to load JSON file using JQuery [duplicate]

The AJAX request works fine, but the moment I add a header via beforeSend or headers, an OPTIONS pre-flight request is made and the GET request is aborted.
Code: $.ajax({
type: "GET",
crossDomain: true,
beforeSend: function (xhr)
{
xhr.setRequestHeader("session", $auth);
},
url: $url,
success: function (data) {
$('#something').html(data);
},
error: function (request, error) {
$('#something').html("<p>Error getting values</p>");
}
});
Similar AJAX Request w/o headers specified (the moment I add/modify header, an OPTIONS call is made)
Request GET /api/something?filter=1 HTTP/1.1
Referer http://app.xyz.dj/dashboard
Accept application/json, text/javascript, */*; q=0.01
Accept-Language en-US
Origin http://app.xyz.dj
Accept-Encoding gzip, deflate
User-Agent Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; MASMJS; rv:11.0) like Gecko
Host 162.243.13.172:8080
DNT 1
Connection Keep-Alive
Cache-Control no-cache
Similar Server Response Header (for GET request)
Response HTTP/1.1 200 OK
Server Apache-Coyote/1.1
Access-Control-Allow-Origin *
Access-Control-Allow-Methods GET, POST, DELETE, PUT, OPTIONS, HEAD
Access-Control-Allow-Headers Content-Type, Accept, X-Requested-With
Access-Control-Allow-Credentials true
Content-Type application/json
Transfer-Encoding chunked
Date Thu, 09 Jan 2014 14:43:07 GMT
What I am doing wrong?
Solved.
Thanks #JasonP for pointers. Changed Server Response Headers from
Access-Control-Allow-Headers:*
to specific ones
Access-Control-Allow-Headers: Content-Type, Accept, X-Requested-With, Session
and now it works!

In PhoneGap App, AJAX call error event gets triggered even the server returns 200 OK status

I am using the below Ajax call to connect with Spring security from crossdomain (PhoneGap). The response I got is 200 OK - it has the expected response in JSON format. But the error event is getting fired due to CORS. On the Spring side, I have added a CORS filter to allow any type of URL (Access-Control-Allow-Origin = ' * ').
$.ajax({
type:'POST',
url: CONTEXTPATH + '/j_spring_security_check',
data: formData,
dataType: 'text json',
cache: false,
crossdomain: false,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-Requested-With' : 'XMLHttpRequest',
},
success: function(data) {
},
error: function(data) {
}
});
The response in the browser console is:
POST XHR http://192.168.0.20:8080/startupbay/j_spring_security_check [HTTP/1.1 200 OK 260ms] Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://192.168.0.20:8080/startupbay/j_spring_security_check. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
The request and response headers are:
RESPONSE HEADER:
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Content-Type, x-requested-with, Origin, Accept
Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS, PATCH, HEAD
Access-Control-Allow-Origin:*
Access-Control-Max-Age:86400
Access-Control-Request-Headers:x-requested-with
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Content-Length:0
Date: Thu, 23 Feb 2017 06:14:39 GMT
Expires:0
Pragma:no-cache
Server:Apache-Coyote/1.1
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block
REQUEST HEADER:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.5
Access-Control-Request-Headers:x-requested-with
Access-Control-Request-Method:POST
Connection:keep-alive
Host:192.168.0.20:8080
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0
origin:http://192.168.0.20:3000
In the Error section, I looked for the error mentioned in 'xhr'. The statusText:error, responseText:'', status:0.
Please help me in resolving this issue.
When I set the crossdomain:true, that time in the browser console I can see only the OPTIONS request, but not followed by the POST request.
Just to add, this issue is appearing only for the '/j_spring_security_check' URL. For another URL, the same type setup is working fine.

jQuery basic authentication doesn't working

I need to make a CORS request to server which uses basic authentication. I use jQuery 1.5.1 and have this code:
$.ajax({
type: 'GET',
global: true,
url: theSource,
crossDomain: true,
beforeSend: function(xhr) {
xhr.withCredentials = true;
xhr.setRequestHeader("Authorization", "Basic " + btoa("username:password"));
},
error: function (xhr, status, errorThrown) {
alert(errorThrown + '\n' + status + '\n' + xhr.statusText);
},
success: function (data) {
ABC.ABCconsole.log('Success');
ABC.openAjaxSuccess(data);
}
});
On a server side setted these headers:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Authorization, Accept
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Origin: http://example.com
Unfortunately in response from server I have 401 Unauthorized error.
In a request I have these headers:
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Connection:keep-alive
Host:example01.com
Origin:http://example.com
Referer:http://example.com/france/asd/qwes/business-nothing.html
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36
And in a response these headers:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Authorization, Accept
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Origin: http://example.com
Content-Length:58
Content-Type:text/html
Date:Wed, 16 Jul 2014 09:42:00 GMT
Server:Microsoft-IIS/7.5
Set-Cookie:loc=phl;path=/;
WWW-Authenticate:Basic realm="example01.com"
May be you have any ideas why it happens?
UPD: As you can see in a request I don't see that my Authentication header is setted. If I running browser with --disable-web-security key everything works fine. And Authentication header is setted properly.
UPD2: Request fails on a http POST method. So may be problem is here?
Remote Address:111.111.11.12:80
Request URL:http://example01.com/asst/index.epx?id=569fe9d0-1515-423a-bae8-84265b6396a0&_=1405506291028
Request Method:OPTIONS
Status Code:401 Unauthorized
Use Access-Control-Allow-Origin: * instead.

Get request failed with custom header

Here is my AngularJS code, (it works fine if I remove the header option).
$http.get(env.apiURL()+'/banks', {
headers: {
'Authorization': 'Bearer '+localStorageService.get('access_token')
}
})
Here is the request:
OPTIONS /banks HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://localhost:8081
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36
Access-Control-Request-Headers: accept, authorization
Accept: */*
Referer: http://localhost:8081/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,vi;q=0.6
And response:
HTTP/1.1 404 Not Found
Access-Control-Allow-Headers: Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Origin: http://localhost:8081
Content-Type: text/plain; charset=utf-8
Date: Mon, 17 Mar 2014 11:05:20 GMT
Content-Length: 19
I added both Accept and Authorization header but the request still fails?
Does the capitalization (I mean authorization vs Authorization) result in that failure? If yes, how can I make AngularJS stop doing that?
if origin := req.Header.Get("Origin"); origin == "http://localhost:8081" {
rw.Header().Set("Access-Control-Allow-Origin", origin)
rw.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
rw.Header().Set("Access-Control-Allow-Headers",
"Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
}
Go server routing code:
r := mux.NewRouter()
r.HandleFunc("/banks", RetrieveAllBank).Methods("GET")
http.ListenAndServe(":8080", r)
OK, the issue because I fotgot to handle the "OPTIONS" request (to make a CORS browser will send a preflight OPTIONS request first and then the 'real' request if accepted by the server).
I only need to modify my Go server (see the comment):
func main() {
r := mux.NewRouter()
r.HandleFunc("/banks", RetrieveAllBank).Methods("GET")
http.ListenAndServe(":8080", &MyServer{r})
}
type MyServer struct {
r *mux.Router
}
func (s *IMoneyServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if origin := req.Header.Get("Origin"); origin == "http://localhost:8081" {
rw.Header().Set("Access-Control-Allow-Origin", origin)
rw.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
rw.Header().Set("Access-Control-Allow-Headers",
"Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
}
// Stop here if its Preflighted OPTIONS request
if req.Method == "OPTIONS" {
return
}
// Lets Gorilla work
s.r.ServeHTTP(rw, req)
}

Categories