2012-06-12 1 views
72

Я написал API REST в экспресс-инфраструктуре для node.js, который работает для запросов из консоли js в Chrome, а также в строке URL и т. Д. I Теперь я пытаюсь заставить его работать для запросов из другого приложения в другом домене (CORS).Разрешить запрос CORS REST в приложение Express/Node.js на Heroku

Первый запрос, сделанный автоматически передним концом javascript, относится к/api/search? Uri = и, как представляется, не работает в запросе OPTIONS «предполетный».

В моей экспресс-приложение, я добавляю заголовки CORS, используя:

var allowCrossDomain = function(req, res, next) { 
    res.header('Access-Control-Allow-Origin', '*'); 
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS'); 
    res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With'); 

    // intercept OPTIONS method 
    if ('OPTIONS' == req.method) { 
     res.send(200); 
    } 
    else { 
     next(); 
    } 
}; 

и:

app.configure(function() { 
    app.use(express.bodyParser()); 
    app.use(express.methodOverride()); 
    app.use(app.router); 
    app.use(allowCrossDomain); 
    app.use(express.static(path.join(application_root, "public"))); 
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
}); 

В консоли Chrome я получаю эти заголовки:

URL запроса: HTTP : //furious-night-5419.herokuapp.com/api/search? uri = http% 3A% 2F% 2Flocalhost% 3A5000% 2Fcollections% 2F1% 2Fdocuments% 2F1

Запрос Метод: ВАРИАНТЫ

Код Статус: 200 OK

Заголовки запросов

Accept:*/* 
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3 
Accept-Encoding:gzip,deflate,sdch 
Accept-Language:en-US,en;q=0.8 
Access-Control-Request-Headers:origin, x-annotator-auth-token, accept 
Access-Control-Request-Method:GET 
Connection:keep-alive 
Host:furious-night-5419.herokuapp.com 
Origin:http://localhost:5000 
Referer:http://localhost:5000/collections/1/documents/1 
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.56 Safari/536.5 

строку запроса Параметры

uri:http://localhost:5000/collections/1/documents/1 

Response Headers

Allow:GET 
Connection:keep-alive 
Content-Length:3 
Content-Type:text/html; charset=utf-8 
X-Powered-By:Express 

Это похоже на отсутствие правильных заголовков, отправляемых приложением API?

Спасибо.

+0

Я получаю эту ошибку в коде, который я не писал, но я не понимаю необходимость обработчика метода 'OPTIONS'. Может ли кто-то помочь мне понять, почему не обрабатывать только метод «POST», а не обрабатывать метод «POST» ** и «OPTIONS»? –

ответ

49

Я прочитал ваш код в чистом приложении ExpressJS, и все работает отлично.

Попробуйте переместить app.use(allowCrossDomain) в начало функции configure.

+8

Причина, по которой это произошло, заключается в том, что вам нужно определить ее до 'app.use (app.router);' Cheers! – Michal

+0

В моем случае следующий POST не вызывается после отправки res.send (200), когда req.method == 'OPTIONS'. я что-то пропустил? – Aldo

+0

2Aldo: необходим код. Может быть, вы забыли некоторые заголовки? Если ваш клиент не отправляет POST после того, как ваш сервер правильно подал запрос предварительной проверки OPTIONS, попробуйте проверить консоль инструментов разработчика. WebKit регистрирует подобные ошибки в консоли веб-инспектора. – Olegas

1

для поддерживающего печенья withCredentials вам нужна эта линия xhr.withCredentials = true;

mdn docs xhr.withCredentials

В Express Server добавить этот блок перед всеми другими

`app.all('*', function(req, res, next) { 
    var origin = req.get('origin'); 
    res.header('Access-Control-Allow-Origin', origin); 
    res.header("Access-Control-Allow-Headers", "X-Requested-With"); 
    res.header('Access-Control-Allow-Headers', 'Content-Type'); 
    next(); 
});` 
0

Это не может быть для большинства людей просматривая этот вопрос, но у меня была такая же проблема, и решение не было связано с CORS.

Оказывается, что секретный токен JSON Web string не был определен в переменных среды, поэтому токен не может быть подписан. Это вызвало любой запрос POST, который полагается на проверку или подпись токена, чтобы получить тайм-аут и вернуть ошибку 503, сообщив браузеру, что в CORS есть что-то не так, что это не так. Добавление переменной окружения в Heroku решило проблему.

Надеюсь, это поможет кому-то.

+0

Да, это была проблема со мной. Не могли бы вы уточнить, как вы решили проблему. Я все еще в разработке и работаю над пакетом Express.js w/node cors. – alan

+0

@alan Я использовал обещания проверить токен в своем приложении, некоторые, как если секрет JWT не определен, обещание никогда не будет разрешено, вот [код] (https://github.com/elbuki/remindr-api /blob/develop/src/middlewares/verifyToken.js) Я использовал, если вам нужна дополнительная ссылка. – CatBrownie

+0

Спасибо, что ответили. Я просмотрю код. По тайне я предполагаю, что вы говорите о втором секретном ключе. Я использую oauth2. – alan

Смежные вопросы