I have a REST api created with the restify module and I want to allow cross-origin resource sharing. What is the best way to do it?
You have to set the server up to set cross origin headers. Not sure if there is a built in use function or not, so I wrote my own.
server.use(
function crossOrigin(req,res,next){
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
return next();
}
);
I found this from this tutorial. http://backbonetutorials.com/nodejs-restify-mongodb-mongoose/
server.opts()
in @cyrusmith's answser. –
Gabrielson The latest version of Restify provides a plugin to handle CORS.
So you can now use it like this:
server.use(restify.CORS({
// Defaults to ['*'].
origins: ['https://foo.com', 'http://bar.com', 'http://baz.com:8081'],
// Defaults to false.
credentials: true,
// Sets expose-headers.
headers: ['x-foo']
}));
restify.CORS()
by itself was sufficient. No need for restify.fullResponse()
, but in the request, you need to specify the Origin
header. See related code comment in cors.js. –
Wilda This works for me:
var restify = require('restify');
var server = restify.createServer();
server.use(restify.CORS());
server.opts(/.*/, function (req,res,next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", req.header("Access-Control-Request-Method"));
res.header("Access-Control-Allow-Headers", req.header("Access-Control-Request-Headers"));
res.send(200);
return next();
});
server.get('/test', function (req,res,next) {
res.send({
status: "ok"
});
return next();
});
server.listen(3000, function () {
console.log('%s listening at %s', server.name, server.url);
});
This is what worked for me:
function unknownMethodHandler(req, res) {
if (req.method.toLowerCase() === 'options') {
console.log('received an options method request');
var allowHeaders = ['Accept', 'Accept-Version', 'Content-Type', 'Api-Version', 'Origin', 'X-Requested-With']; // added Origin & X-Requested-With
if (res.methods.indexOf('OPTIONS') === -1) res.methods.push('OPTIONS');
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Headers', allowHeaders.join(', '));
res.header('Access-Control-Allow-Methods', res.methods.join(', '));
res.header('Access-Control-Allow-Origin', req.headers.origin);
return res.send(204);
}
else
return res.send(new restify.MethodNotAllowedError());
}
server.on('MethodNotAllowed', unknownMethodHandler);
I this code was taken from https://github.com/mcavage/node-restify/issues/284
server.use(restify.fullResponse());
prior to the call to server.on(...)
. –
Milliemillieme server.opts({path: '/customers', version: '0.0.1'}, unknownMethodHandler);
. With on
, the method just wasn't called. –
Soule CORS Plugin is deprecated in favor of https://github.com/Tabcorp/restify-cors-middleware. (Source: https://github.com/restify/node-restify/issues/1091.)
Below is a sample code regarding how to use
const corsMiddleware = require('restify-cors-middleware')
const cors = corsMiddleware({
preflightMaxAge: 5, //Optional
origins: ['http://api.myapp.com', 'http://web.myapp.com'],
allowHeaders: ['API-Token'],
exposeHeaders: ['API-Token-Expiry']
})
server.pre(cors.preflight)
server.use(cors.actual)
If anyone comes across this as of Feb 2018 there seems to be a bug that's been introduced, I couldn't get the restify-cors-middleware
to work.
I'm using this work around for now:
server.pre((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
next();
});
To enable CORS for basic authentication I did the following. It did not work until the .pre
methods were used instead of the .use
methods
server.pre(restify.CORS({
origins: ['https://www.allowedip.com'], // defaults to ['*']
credentials: true,
headers: ['X-Requested-With', 'Authorization']
}));
server.pre(restify.fullResponse());
function unknownMethodHandler(req, res) {
if (req.method.toLowerCase() === 'options') {
var allowHeaders = ['Accept', 'Accept-Version', 'Content-Type', 'Api-Version', 'Origin', 'X-Requested-With', 'Authorization']; // added Origin & X-Requested-With & **Authorization**
if (res.methods.indexOf('OPTIONS') === -1) res.methods.push('OPTIONS');
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Headers', allowHeaders.join(', '));
res.header('Access-Control-Allow-Methods', res.methods.join(', '));
res.header('Access-Control-Allow-Origin', req.headers.origin);
return res.send(200);
} else {
return res.send(new restify.MethodNotAllowedError());
}
}
server.on('MethodNotAllowed', unknownMethodHandler);
I do it like this on my restify base app:
//setup cors
restify.CORS.ALLOW_HEADERS.push('accept');
restify.CORS.ALLOW_HEADERS.push('sid');
restify.CORS.ALLOW_HEADERS.push('lang');
restify.CORS.ALLOW_HEADERS.push('origin');
restify.CORS.ALLOW_HEADERS.push('withcredentials');
restify.CORS.ALLOW_HEADERS.push('x-requested-with');
server.use(restify.CORS());
you need to use restify.CORS.ALLOW_HEADERS.push method to push the header u want into restify first, then using the CORS middleware to boot the CORS function.
./node_modules/restify/lib/plugins/cors.js
. –
Eldwon MOST OF THE PREVIOUS ANSWERS ARE FROM 2013 AND USE DEPRECATED EXAMPLES! The solution (in 2017 at least) is as follows:
npm install restify-cors-middleware
Then in your server javascript file:
var corsMiddleware = require('restify-cors-middleware');
var cors = corsMiddleware({
preflightMaxAge: 5,
origins: ['*']
});
var server = restify.createServer();
server.pre(cors.preflight);
server.use(cors.actual);
And add whatever additional other options work for you. My use case was creating a localhost proxy to get around browser CORS issues during devolopment. FYI I am using restify as my server, but then my POST from the server (and to the server) is with Axios. My preference there.
This sufficed in my case:
var server = restify.createServer();
server.use(restify.fullResponse());
server.get('/foo', respond(req, res, next) {
res.send('bar');
next();
});
It wasn't necessary to server.use(restify.CORS());
Also, it appears server.use()
calls must precede server.get()
calls in order to work.
This worked for me with restify 7
server.pre((req, res, next) => {
res.header('Access-Control-Allow-Origin', req.header('origin'));
res.header('Access-Control-Allow-Headers', req.header('Access-Control-Request-Headers'));
res.header('Access-Control-Allow-Credentials', 'true');
// other headers go here..
if(req.method === 'OPTIONS') // if is preflight(OPTIONS) then response status 204(NO CONTENT)
return res.send(204);
next();
});
I am using Restify 7.2.3 version and this code worked for me very well. You need to install the restify-cors-middleware plugin.
const corsMiddleware = require('restify-cors-middleware')
const cors = corsMiddleware({
preflightMaxAge: 5, //Optional
origins: ['http://ronnie.botsnbytes.com', 'http://web.myapp.com'],
allowHeaders: ['API-Token'],
exposeHeaders: ['API-Token-Expiry']
})
server.pre(cors.preflight)
server.use(cors.actual)
const cors = require('cors');
const server = restify.createServer();
server.use(cors());
This worked for me
const restify = require('restify');
const corsMiddleware = require('restify-cors-middleware');
const cors = corsMiddleware({
origins: ['*']
});
const server = restify.createServer();
server.pre(cors.preflight);
server.use(cors.actual);
server.get('/api/products', (request, response) => {
response.json({ message: 'hello REST API' });
});
server.listen(3000, () => console.info(`port 3000`));
... is one brute-force solution, though you should be very careful doing that.
© 2022 - 2024 — McMap. All rights reserved.