meteor-restivus
meteor-restivus copied to clipboard
CORS not working (again) from Chrome Widget. Here's a solution
Suddenly CORS stopped working again for my Chrome widget, so for the community's sake; here's a solution that does work:
The problem is that the Restivus OPTIONS response is ignoring the enableCors
and defaultHeaders
as set (or if not set, the default) in the Restivus config. But only in the case of calling the API from a Chrome widget. When called from web / Postman there is no problem.
So you have to setup that manually. Here's the solution that does work:
Api.addRoute 'collections', authRequired: true,
get: () ->
# do something
return {
status: "success"
header:
'Content-Type': 'application/json'
'Access-Control-Allow-Origin': '*'
'Access-Control-Allow-Headers': 'X-Auth-Token, X-User-Id'
}
options: ->
return {
'Content-Type': 'application/json'
'Access-Control-Allow-Origin': '*'
'Access-Control-Allow-Headers': 'X-Auth-Token, X-User-Id'
}
Unfortunately you have to do that for every route and endpoint, but at least you have fine-grain control over the options response.
I don't know why this response to a Chrome widgets ajax call would be different than from the web. You might want to check into that at some point.
Hi Satya!
Did you know you can setup a default OPTIONS endpoint that will run for all routes? That should help you DRY up the code so you don't have to implement the OPTIONS endpoint on every single route.
Even better than that, I think I've actually resolved this issue in #99. I setup the default OPTIONS endpoint with CORS headers whenever enableCors: true
. I'm just waiting for someone to test out the code on faa77e09e458540cfcde6a4cc39730a4ab5c2807. Would you mind trying it out and letting me know if it works for you? Do you know how to test a local package? You just need to move it into your packages
directory within your meteor app and meteor will detect it in place of the published version (just make sure to specify the correct version).
Let me know if any of that doesn't work for you for some reason (it's tested and should work fine). Thanks (as always) for reporting the issue, and especially for suggesting a solution!
EDIT: Once faa77e09e458540cfcde6a4cc39730a4ab5c2807 is tested I can publish it shortly after that
Hi that's what I'm saying. That doesn't work in this case. It's just being ignored:
The problem is that the Restivus OPTIONS response is ignoring the enableCors and defaultHeaders as set (or if not set, the default) in the Restivus config.
You must set it per route & endpoint
Exactly. That's an issue with the currently published version. I've fixed it in the commit I've referenced above. Are you saying you tried that version and it still doesn't work?
Ok right, sorry, No I haven't tried that. I will and let you know.
FYI: I've updated to 0.8.4, DRYed up the code, my config is now simply:
Api = new Restivus
useDefaultAuth: true
enableCors: true
but it doesn't work:
XMLHttpRequest cannot load https://our.postjar.com/api/collections. Invalid HTTP status code 405
Looking at the request / response
Request Headers
view parsed
OPTIONS /api/collections HTTP/1.1
Host: our.postjar.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: GET
Origin: chrome-extension://kaagfgncegpdenjlhoekjfigancflibd
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.155 Safari/537.36
Access-Control-Request-Headers: accept, x-auth-token, x-user-id
Accept: */*
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en,nl;q=0.8,en-US;q=0.6,es;q=0.4
Response Headers
view parsed
HTTP/1.1 405 Method Not Allowed
Set-Cookie: cluster-endpoint::web=96eb97e58f605bd62c2d9a0e10051432a93916c9; path=/; httponly
Vary: Accept-Encoding
content-type: application/json
access-control-allow-origin: *
allow: GET
Date: Tue, 18 Aug 2015 19:51:32 GMT
Connection: keep-alive
Transfer-Encoding: chunked
you can see that the OPTIONS
is still missing the headers. I'm sticking with my solution, at least that works, providing all the headers correctly
Yea, can confirm is still the same problem. But @satyavh solution works. Also placed it in the defaultOptionsEndpoint
to DRY it up and that works too.
I am using Restivus to demonstrate REST implementation in my book. I am trying to create users in Meteor.js application via REST API. I have followed the steps provided in the documentation. But ended up in CORS issue. The application is simple meteor application. The code I had tried is given below:
var API = new Restivus({
useDefaultAuth: true,
prettyJson: true,
defaultHeaders: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Content-Type': 'application/json'
},
defaultOptionsEndpoint: function() {
this.response.writeHead(201, {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',
'Content-Type': 'application/json',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
});
return;
},
enableCors: true
});
Still it is not working and when I make request from other domain, I get the error
XMLHttpRequest cannot load http://localhost:3001/api/users. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
Can someone point me how to add the appropriate headers with a working code snippet? I am using version 0.8.4.
Edit: I am making request form browser via XMLHttpRequest.
Figured out the issue. I din't add Accounts-Password package. @kahmali The error was in appropriate. The createUser
method was throwing exception but it wasn't visible either in the response or in the server console. After hours of debugging in meteor debug mode, I figured it out. Anyways, thanks for the package.
Where is solution about this problem?
ApiV1 = new Restivus({ prettyJson: true, enableCors: true, defaultHeaders: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Content-Type': 'application/json' } });
request :
$.ajax({ url: "http://crossorigin.me/http://localhost:8082/api/"+topic.type+"?topic="+topic.utente+","+topic.corsa+";"+topic.descrizione, dataType:'json', crossOrigin: true, async: false, success: function (data) { if (data.status === "OK"){ //alert("data= "+data); Notifications.new({ title: data, link: '/messages/1' }); } } });
if I use proxy this is the error: GET http://crossorigin.me/http://localhost:8082/api/publisher?topic=4JkWvxSZg8f…F,gdKz6msEuzgppTYQX;richiesta%20prenotazione%20Utente%20:4JkWvxSZg8fKCC7TF 500 (Internal Server Error)
Otherwise :
XMLHttpRequest cannot load http://localhost:8082/api/publisher?topic=4JkWvxSZg8fKCC7TF,w8SGov2oh3DcAgXk3;richiesta%20prenotazione%20Utente%20:4JkWvxSZg8fKCC7TF. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
how can I do to fix this error ( or bug) ?
I am still having this same error. Any thoughts on a solution?
Have you tried @satyavh's and @justindra's suggestions above? That seemed to resolve the issue for them.
Unfortunately, I'm tied up with another project at the moment, so I'm not sure when I'll have time to look into this any further. Sorry I can't be more help!
@bvjebin Sorry I never got back to you. You resolved your issue pretty quickly. Just curious: what is this book you're writing? Is it available online? Thank you for using Restivus as an example for building REST APIs in Meteor. I'm honored!
I have problem with CORS to. Even with this:
Api = new Restivus({
enableCors:true,
version: 'v1',
prettyJson: true,
defaultHeaders: {
"Vary":"Accept-Encoding",
"Access-Control-Allow-Methods":"POST",
"Access-Control-Allow-Headers":"X-PINGOTHER",
"Access-Control-Allow-Origin":"*",
"Content-Type":"application/json",
"Content-Encoding":"gzip",
"Date":new Date(),
"Transfer-Encoding":"chunked"
},
});
Api.addRoute('traces',{
post: function () {
Meteor._debug('pooost');
return {
status: "success",
header:{
"Vary":"Accept-Encoding",
"Access-Control-Allow-Methods":"POST",
"Access-Control-Allow-Headers":"X-PINGOTHER",
"Access-Control-Allow-Origin":"*",
"Content-Type":"application/json",
"Content-Encoding":"gzip",
"Date":new Date(),
"Transfer-Encoding":"chunked"
}
}
},
options: function(){
Meteor._debug('options');
return {
status: "success",
header:{
"Vary":"Accept-Encoding",
"Access-Control-Allow-Methods":"POST",
"Access-Control-Allow-Headers":"X-PINGOTHER",
"Access-Control-Allow-Origin":"*",
"Content-Type":"application/json",
"Content-Encoding":"gzip",
"Date":new Date(),
"Transfer-Encoding":"chunked"
}
}
}
});
I get this:
HTTP/1.1 200 OK
vary: Accept-Encoding
content-type: text/html; charset=utf-8
date: Tue, 24 Nov 2015 22:39:41 GMT
connection: keep-alive
transfer-encoding: chunked
Missing the Access-Control-Allow-Origin:*
I have created rest service with following config
// Global API configuration
ApiV1 = new Restivus({
version: 'v1',
useDefaultAuth: false,
prettyJson: true,
enableCors: true,
defaultHeaders: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Z-Key, x-user-id,x-auth-token',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Content-Type': 'application/json'
},
defaultOptionsEndpoint: function() {
this.response.writeHead(201, {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Z-Key',
'Content-Type': 'application/json',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
});
return;
},
});
I'm not using default auth I create my own routes for /login and /logout
when try to access page, it is throwing following error
OPTIONS https://test-api.site.io/api/v1/login/ 502 (Bad Gateway)HTTP.call @ http.js?
and
XMLHttpRequest cannot load https://test-api.site.io/api/v1/login/. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://meteor.local' is therefore not allowed access. The response had HTTP status code 502.
Same problem here with the DELETE method
Api = new Restivus({
apiPath: 'api/',
prettyJson: true,
useDefaultAuth: true,
version: 'v0',
enableCors: true
});
and
delete: {
action: function() {
Invitations.remove({_id : this.urlParams.id});
return {
statusCode: 200,
data : {
status: "success",
},
headers : {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'X-Auth-Token, X-User-Id',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
}
}
}
Do not work.
I am using 0.8.4 version
@sabativi did you tried with setting up defaultOptionsEndpoint
?
defaultOptionsEndpoint: function() {
this.response.writeHead(201, {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Z-Key',
'Content-Type': 'application/json',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
});
},
Indeed it works now Thanks
@sabativi What is the solution !?
@sabativi and @sasikanth513,
I wanted to post a slightly modified version of the defaultOptionsEndpoint because it was failing for me on two counts:
- It was not returning anything and my logs on Modulus were registering "Cannot return null or undefined from an endpoint".
- Your snippet lacks
this.done();
which is clearly required per the documentation.
So here's what I ended up with:
Api = new Restivus({
enableCors: true,
useDefaultAuth: false,
prettyJson: true,
defaultOptionsEndpoint: {
action: function () {
this.response.writeHead(201, {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Z-Key',
'Content-Type': 'application/json',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS'
});
this.done();
return {
status: "success",
"data": {
"message": "We love OPTIONS"
}
};
}
}
});
@RenMan Just a heads up that there's another known issue that may sneak up on you when calling this.done()
that I can take care of very quickly next time I make some updates to Restivus. I would have fixed it up the other day but I overlooked it.
I had this issue with PUT request coming from any browser. No problems at all with CURL or POSTMAN. I fixed it by modifying our PUT endpoints to something like this:
...
put: function(){
return {
status: 'success',
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Z-Key',
},
body: 'There is nothing here!',
data: result,
};
},
options: function() {
return {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Z-Key',
},
body: 'There is nothing here!'
};
},
And also I just want to confirm, enableCors
, defaultHeaders
, defaultOptionsEndpoint
are stil being ignored idk why.
Once you have your endpoints setup like mine above, you can now omit contentType:'application/json'
from the ajax
options:
$.ajax({
url: `https://yoursever/userid/EbwfagAcYFy8rxWNb`,
type: 'PUT',
dataType: "json",
crossDomain: true,
data:{ 'works': true }
}).done((response) => {
if(response.status == 'success'){
browserHistory.push(url);
}
}).fail(function(response){
console.log(response);
});
Dont worry if it sends your data as content-type:application/x-www-form-urlencoded; charset=UTF-8
. Restivus can handle it as long as you use this.bodyParams
in your endpoint handler in the server.
Thanks everyone!
@sabativi did you tried with setting up
defaultOptionsEndpoint
?defaultOptionsEndpoint: function() { this.response.writeHead(201, { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Z-Key', 'Content-Type': 'application/json', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', }); },
For me this work only for status code 200, but for any other status code like 422, 401, 400 etc, i get CORS Missing Allow Origin
, How should I make it working all the status codes?