Как разрешить CORS?


Я пытаюсь поддерживать CORS в моем узле.JS приложение, которое использует Экспресс.веб-фреймворк на JS. Я читал групповое обсуждение Google о том, как справиться с этим, и прочитать несколько статей о том, как работает CORS. Во-первых, я сделал это (код написан в синтаксисе CoffeeScript):

app.options "*", (req, res) ->
  res.header 'Access-Control-Allow-Origin', '*'
  res.header 'Access-Control-Allow-Credentials', true
  # try: 'POST, GET, PUT, DELETE, OPTIONS'
  res.header 'Access-Control-Allow-Methods', 'GET, OPTIONS'
  # try: 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept'
  res.header 'Access-Control-Allow-Headers', 'Content-Type'
  # ...

это, кажется, не работает. Похоже, что мой браузер (Chrome) не отправляет запрос на начальные параметры. Когда я только что обновил блок для ресурса, мне нужно отправить cross-origin получить запрос на:

app.get "/somethingelse", (req, res) ->
  # ...
  res.header 'Access-Control-Allow-Origin', '*'
  res.header 'Access-Control-Allow-Credentials', true
  res.header 'Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS'
  res.header 'Access-Control-Allow-Headers', 'Content-Type'
  # ...

Он работает (в Chrome). Это также работает в Safari.

Я читал, что...

в браузере, реализующем CORS, каждому перекрестному запросу GET или POST предшествует запрос OPTIONS, который проверяет, является ли GET или POST в порядке.

Итак, мой главный вопрос: почему это не происходит в моем случае? Почему это не мое приложение.параметры блока называется? Почему мне нужно установить заголовки в моем главное приложение.получить блок?

22 502

22 ответа:

чтобы ответить на ваш главный вопрос, спецификация CORS требует только вызова опций, чтобы предшествовать сообщению или GET, если сообщение или GET имеет в нем какой-либо непростой контент или заголовки.

типы контента, требующие предварительного запроса CORS (вызов опций), являются любыми типами контента за исключением:

  1. application/x-www-form-urlencoded
  2. multipart/form-data
  3. text/plain

любые другие типы контента, кроме перечисленных выше будет запущен запрос перед полетом.

что касается заголовков, любые заголовки запроса только после вызовет запрос перед полетом:

  1. Accept
  2. Accept-Language
  3. Content-Language
  4. Content-Type
  5. DPR
  6. Save-Data
  7. Viewport-Width
  8. Width

любые другие заголовки запроса вызовут предварительный полет запрос.

таким образом, вы можете добавить пользовательский заголовок, такой как: x-Trigger: CORS, и это должно вызвать запрос перед полетом и нажать блок опций.

посмотреть MDN Web API Reference - CORS Preflighted requests

Я нашел самый простой способ-использовать узел.пакет Яш cors. Самое простое использование:

var cors = require('cors')

var app = express()
app.use(cors())

есть, конечно, много способов настроить поведение в соответствии с вашими потребностями; страница, связанная выше, показывает ряд примеров.

попробуйте передать управление на следующий соответствующий маршрут. Если Экспресс соответствует приложение.сначала получите маршрут, затем он не будет продолжаться на маршруте опций, если вы не сделаете это (Примечание использование next):

app.get('somethingelse', function(req, res, next) {
    //..set headers etc.

    next();
});

что касается организации материала CORS, я поместил его в промежуточное программное обеспечение, которое хорошо работает для меня:

//CORS middleware
var allowCrossDomain = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', 'example.com');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');

    next();
}

//...
app.configure(function() {
    app.use(express.bodyParser());
    app.use(express.cookieParser());
    app.use(express.session({ secret: 'cool beans' }));
    app.use(express.methodOverride());
    app.use(allowCrossDomain);
    app.use(app.router);
    app.use(express.static(__dirname + '/public'));
});

чтобы остаться в той же идее маршрутизации. Я использую этот код :

app.all('/*', function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  next();
});

похоже на http://enable-cors.org/server_expressjs.html пример

do

npm install cors --save

и просто добавьте эти строки в свой основной файл, куда идет ваш запрос.

const cors = require('cors');
const express = require('express');
let app = express();
app.use(cors());
app.options('*', cors());

Я сделал более полное промежуточное программное обеспечение, подходящее для express или connect. Он поддерживает OPTIONS запросы на предполетную проверку. Обратите внимание, что это позволит CORS доступ ко всему, вы можете поставить некоторые проверки, если вы хотите ограничить доступ.

app.use(function(req, res, next) {
    var oneof = false;
    if(req.headers.origin) {
        res.header('Access-Control-Allow-Origin', req.headers.origin);
        oneof = true;
    }
    if(req.headers['access-control-request-method']) {
        res.header('Access-Control-Allow-Methods', req.headers['access-control-request-method']);
        oneof = true;
    }
    if(req.headers['access-control-request-headers']) {
        res.header('Access-Control-Allow-Headers', req.headers['access-control-request-headers']);
        oneof = true;
    }
    if(oneof) {
        res.header('Access-Control-Max-Age', 60 * 60 * 24 * 365);
    }

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

установите CORS модуль expressjs. вы можете выполнить следующие действия >

установка

npm install cors

простое использование (включить все запросы CORS)

var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());

для получения более подробной информации перейдите к https://github.com/expressjs/cors

сделать что-то вроде этого:

app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});

тестирование выполняется с помощью express + node + ionic, работающего в разных портах.

Localhost:8100

Localhost:5000

// CORS (Cross-Origin Resource Sharing) headers to support Cross-site HTTP requests

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

сначала просто установите cors в вашем проекте. Возьмите терминал (командная строка) и cd в каталог проекта и выполните следующую команду:

npm install cors --save
сервер.js файл и изменить код, чтобы добавить в него следующее:
var cors = require('cors');


var app = express();

app.use(cors());

app.use(function(req, res, next) {
   res.header("Access-Control-Allow-Origin", "*");
   res.header('Access-Control-Allow-Methods', 'DELETE, PUT, GET, POST');
   res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
   next();
});

это работает для меня..

это работает для меня, так как его простая реализация внутри маршрутов, im с помощью meanjs и его работы отлично, safari, chrome и т. д.

app.route('/footer-contact-form').post(emailer.sendFooterMail).options(function(req,res,next){ 
        res.header('Access-Control-Allow-Origin', '*'); 
        res.header('Access-Control-Allow-Methods', 'GET, POST');
        res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
        return res.send(200);

    });

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

сначала ты нужно установитьcors С помощью команды ниже:

npm install cors --save

теперь добавить следующий код для вашего приложения стартовый файл, как ( app.js or server.js)

var express = require('express');
var app = express();

var cors = require('cors');
var bodyParser = require('body-parser');

//enables cors
app.use(cors({
  'allowedHeaders': ['sessionId', 'Content-Type'],
  'exposedHeaders': ['sessionId'],
  'origin': '*',
  'methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
  'preflightContinue': false
}));

require('./router/index')(app);

Если вы хотите сделать его конкретным контроллером, вы можете использовать:

res.setHeader('X-Frame-Options', 'ALLOWALL');
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'POST, GET');
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');

обратите внимание, что это также позволит iframes.

мое самое простое решение с Express 4.2.0 (EDIT: похоже, не работает в 4.3.0) было:

function supportCrossOriginScript(req, res, next) {
    res.status(200);
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Content-Type");

    // res.header("Access-Control-Allow-Headers", "Origin");
    // res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    // res.header("Access-Control-Allow-Methods","POST, OPTIONS");
    // res.header("Access-Control-Allow-Methods","POST, GET, OPTIONS, DELETE, PUT, HEAD");
    // res.header("Access-Control-Max-Age","1728000");
    next();
}

// Support CORS
app.options('/result', supportCrossOriginScript);

app.post('/result', supportCrossOriginScript, function(req, res) {
    res.send('received');
    // do stuff with req
});

Я полагаю, что делаю app.all('/result', ...) тоже будет работать...

в дополнение к тому, что говорили другие, не забывайте, что если вы не используете nodemon, вам нужно будет перезапустить сервер узлов, чтобы изменения вступили в силу!

Я лично обновлял свой браузер по привычке, забыв, что это код на стороне сервера.

Я обнаружил, что это очень легко сделать с помощью пакета запросов npm (https://www.npmjs.com/package/request)

тогда я основал свое решение на этом посте http://blog.javascripting.com/2015/01/17/dont-hassle-with-cors/

'use strict'

const express = require('express');
const request = require('request');

let proxyConfig = {
    url : {
        base: 'http://servertoreach.com?id=',
    }
}

/* setting up and configuring node express server for the application */
let server = express();
server.set('port', 3000);


/* methods forwarded to the servertoreach proxy  */
server.use('/somethingElse', function(req, res)
{
    let url = proxyConfig.url.base + req.query.id;
    req.pipe(request(url)).pipe(res);
});


/* start the server */
server.listen(server.get('port'), function() {
    console.log('express server with a proxy listening on port ' + server.get('port'));
});

мы можем избежать CORS и перенаправить запросы на другой сервер вместо этого:

// config:
var public_folder = __dirname + '/public'
var apiServerHost = 'http://other.server'

// code:
console.log("starting server...");

var express = require('express');
var app = express();
var request = require('request');

// serve static files
app.use(express.static(public_folder));

// if not found, serve from another server
app.use(function(req, res) {
    var url = apiServerHost + req.url;
    req.pipe(request(url)).pipe(res);
});

app.listen(80, function(){
    console.log("server ready");
});

я использовал следующие шаги для моего веб-приложения, и у меня был успех:

добавьте пакет cors в экспресс:

npm install cors --save

добавить следующие строки после настройки bodyParser. У меня были некоторые проблемы с добавлением перед bodyParser:

 // enable cors to the server
const corsOpt = {
    origin: process.env.CORS_ALLOW_ORIGIN || '*', // this work well to configure origin url in the server
    methods: ['GET', 'PUT', 'POST', 'DELETE', 'OPTIONS'], // to works well with web app, OPTIONS is required
    allowedHeaders: ['Content-Type', 'Authorization'] // allow json and token in the headers
};
app.use(cors(corsOpt)); // cors for all the routes of the application
app.options('*', cors(corsOpt)); // automatic cors gen for HTTP verbs in all routes, This can be redundant but I kept to be sure that will always work.

использование Express Middleware отлично подходит для меня. Если вы уже используете Express, просто добавьте следующие правила промежуточного программного обеспечения. Он должен начать работать.

app.all("/api/*", function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
  res.header("Access-Control-Allow-Methods", "GET, PUT, POST");
  return next();
});

app.all("/api/*", function(req, res, next) {
  if (req.method.toLowerCase() !== "options") {
    return next();
  }
  return res.send(204);
});

ссылка

может ссылаться на код ниже для того же самого. Источник:Academind / node-restful-api

const express = require('express');
const app = express();

//acts as a middleware
//to handle CORS Errors
app.use((req, res, next) => { //doesn't send response just adjusts it
    res.header("Access-Control-Allow-Origin", "*") //* to give access to any origin
    res.header(
        "Access-Control-Allow-Headers",
        "Origin, X-Requested-With, Content-Type, Accept, Authorization" //to give access to all the headers provided
    );
    if(req.method === 'OPTIONS'){
        res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, GET'); //to give access to all the methods provided
        return res.status(200).json({});
    }
    next(); //so that other routes can take over
})

ниже код будет работать ,но Сначала установите cors by:

npm install --save cors

затем:

module.exports = function(app) { 
var express = require("express");
var cors = require('cors');
var router = express.Router();
app.use(cors());

app.post("/movies",cors(), function(req, res) { 
res.send("test");
});

в TypeScript, если вы хотите использовать узел.пакет Яш cors

/**
* app.ts
* If you use the cors library
*/

import * as express from "express";
[...]
import * as cors from 'cors';

class App {
   public express: express.Application;

   constructor() {
       this.express = express();
       [..]
       this.handleCORSErrors();
   }

   private handleCORSErrors(): any {
       const corsOptions: cors.CorsOptions = {
           origin: 'http://example.com',
           optionsSuccessStatus: 200
       };
       this.express.use(cors(corsOptions));
   }
}

export default new App().express;

Если вы не хотите использовать библиотеки третьей части для обработки ошибок cors, вам нужно изменить метод handleCORSErrors ().

/**
* app.ts
* If you do not use the cors library
*/

import * as express from "express";
[...]

class App {
   public express: express.Application;

   constructor() {
       this.express = express();
       [..]
       this.handleCORSErrors();
   }

   private handleCORSErrors(): any {
       this.express.use((req, res, next) => {
           res.header("Access-Control-Allow-Origin", "*");
           res.header(
               "Access-Control-ALlow-Headers",
               "Origin, X-Requested-With, Content-Type, Accept, Authorization"
           );
           if (req.method === "OPTIONS") {
               res.header(
                   "Access-Control-Allow-Methods",
                   "PUT, POST, PATCH, GET, DELETE"
               );
               return res.status(200).json({});
           } 
           next(); // send the request to the next middleware
       });
    }
}

export default new App().express;

для использования приложения.файл TS

/**
* server.ts
*/
import * as http from "http";
import app from "./app";

const server: http.Server = http.createServer(app);

const PORT: any = process.env.PORT || 3000;
server.listen(PORT);