ทำไมไม่เพิ่มส่วนหัว CORS ในเส้นทางตัวเลือกอนุญาตให้เบราว์เซอร์เข้าถึง API ของฉัน


653

ฉันพยายามสนับสนุน CORS ในแอปพลิเคชัน Node.js ของฉันซึ่งใช้เว็บเฟรมเวิร์ก Express.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) ไม่ได้ส่งคำขอตัวเลือกเริ่มต้น เมื่อฉันเพิ่งอัปเดตบล็อกสำหรับทรัพยากรฉันต้องส่งคำขอ GET แบบข้ามต้นทางไปที่:

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 นั้นตกลงหรือไม่

ดังนั้นคำถามหลักของฉันคือทำไมสิ่งนี้ดูเหมือนจะไม่เกิดขึ้นในกรณีของฉัน? ทำไมแอปของฉันไม่บล็อกตัวเลือกเรียกว่า ทำไมฉันต้องตั้งค่าส่วนหัวในแอพหลัก get.get ของฉัน


2
กฎทองของ CoffeeScript คือ: "มันเป็นแค่จาวาสคริปต์"
SSH

คำตอบนี้อาจมีประโยชน์: stackoverflow.com/a/58064366/7059557
AmirReza-Farahlagha

คำตอบ:


185

เพื่อตอบคำถามหลักของคุณข้อมูลจำเพาะ CORS ต้องการเพียงการเรียกตัวเลือกเพื่อนำหน้า POST หรือ GET หาก POST หรือ 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และที่ควรทริกเกอร์คำขอก่อนบินและกดบล็อก OPTIONS

ดูการอ้างอิง MDN Web API - คำขอ CORS preflighted


11
คุณสามารถยกตัวอย่างได้หรือไม่?
เกลนเพียร์ซ

3
หน้าที่ฉันลิงก์ไปดูเหมือนจะมีตัวอย่างอยู่จำนวนหนึ่ง คุณสามารถบอกฉันว่าตัวอย่างที่คุณคิดว่าหายไป?
Dobes Vandermeer

7
โดยทั่วไปแล้วคำตอบสำหรับลิงก์อย่างเดียวนั้นมีความเปราะบางเพราะสามารถทำได้ทุกเวลา ที่กล่าวว่าคำตอบนี้ดูเหมือนจะดีพอที่จะเน้นเงื่อนไขทั่วไปภายใต้OPTIONSบล็อกที่ไม่ส่ง คงจะดีถ้ามันมีรายชื่อได้รับการยอมรับHEADERSหรือที่content-typesต้องOPTIONSฯลฯ แต่มันเป็นจุดเริ่มต้นที่ดี
dwanderson

668

ผมพบว่าวิธีที่ง่ายที่สุดคือการใช้แพคเกจ Node.js ล ธ การใช้งานที่ง่ายที่สุดคือ:

var cors = require('cors')

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

แน่นอนว่ามีหลายวิธีในการกำหนดค่าพฤติกรรมตามความต้องการของคุณ หน้าลิงค์ด้านบนแสดงตัวอย่างจำนวนหนึ่ง


1
มันล้มเหลวสำหรับฉันเมื่อฉันใช้กับข้อมูลประจำตัว :( ทุกอย่างอื่นทำงานเหมือนมีเสน่ห์ .. แต่มันไม่มีประโยชน์กับฉันถ้ามันล้มเหลวด้วยการตั้งค่าตัวจริงให้เป็นจริง
Sambhav Sharma

มันทำงานได้ดีสำหรับคำขออาแจ็กซ์ ฉันต้องการการใช้งาน CORS สำหรับแท็กสคริปต์และ iFrame เพราะในคำขอเหล่านี้ Origin ไม่มีอยู่ในส่วนหัวของคำขอ :( จะใช้งานได้อย่างไร?
akashPatra

59
คุณต้องตั้งcors({credentials: true, origin: true})
nlawson

2
คุณเปิดใช้งานตัวเลือก preflight ที่นี่ได้อย่างไร
chovy

@nlawson ahh คุณช่วยฉัน
Adrin

446

ลองผ่านการควบคุมไปยังเส้นทางที่ตรงกันถัดไป ถ้า Express จับคู่เส้นทาง app.get ก่อนแล้วจะไม่ดำเนินการต่อไปยังเส้นทางตัวเลือกเว้นแต่ว่าคุณจะทำสิ่งนี้(หมายเหตุการใช้ถัดไป) :

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'));
});

1
ผมเชื่อว่าตัวเลือกที่เกิดขึ้นก่อนที่จะ GET ในขณะที่ถ้าคุณกำลังทำโพสต์ - ไม่มีตัวเลือกขอ ...
นิค

21
คือconfig.allowedDomainsสตริงที่คั่นด้วยจุลภาคหรืออาร์เรย์?
pixelfreak

2
config.allowedDomains ควรเป็นอาเรย์ที่คั่นด้วยช่องว่าง
mcfedr

1
เซสชั่นพิเศษถูกลบออกโดยเพียงแค่จัดลำดับคำสั่งมิดเดิลแวร์ด่วน ในหมายเหตุอื่น ๆ สิ่งนี้ต้องการความปลอดภัยเพิ่มขึ้นเล็กน้อย หากต้นกำเนิดไม่ได้อยู่ในโดเมนที่ได้รับอนุญาตการร้องขอจะยังคงดำเนินการเฉพาะเบราว์เซอร์เท่านั้นที่จะไม่สามารถมองเห็นได้รวมถึงต้นกำเนิดสามารถปลอมแปลงได้ คำแนะนำของฉันจะทำการตรวจสอบและถ้าต้นกำเนิดไม่อยู่ในรายการที่อนุญาตแล้วส่งคืน 403 ทันที นอกจากนี้ยังมีการให้บริการข้อมูลที่ละเอียดอ่อนตรวจสอบผู้ใช้ผ่านเซสชัน
Xerri

1
@mcfedr คุณช่วยอธิบายหน่อยได้ไหมว่าช่องว่างที่คั่นด้วยช่องว่างหมายถึงอะไร?
pootzko

116

ที่จะอยู่ในความคิดเดียวกันของการกำหนดเส้นทาง ฉันใช้รหัสนี้:

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ตัวอย่าง


1
สิ่งนี้จะไปในไฟล์ grunt.js หรือไม่
Oliver Dixon

4
แล้ว preflight ล่ะ?
backdesk

ไม่มี @OliverDixon นี่คือฝั่งเซิร์ฟเวอร์
Alexandre Magno Teles Zimerer

84

ทำ

npm install cors --save

และเพิ่มบรรทัดเหล่านี้ในไฟล์หลักที่คุณต้องการ (เก็บไว้ก่อนเส้นทางใด ๆ )

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

3
app.options('*', cors())// รวมก่อนเส้นทางอื่น ๆ
Rajeshwar

52

ฉันทำมิดเดิลแวร์ที่สมบูรณ์มากขึ้นที่เหมาะสมสำหรับการแสดงหรือเชื่อมต่อ รองรับOPTIONSการร้องขอการตรวจสอบ preflight โปรดทราบว่าจะอนุญาตให้ 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();
    }
});

สวัสดีฉันพบโซลูชันของคุณและสงสัยว่าควรตั้งค่าสถานะ 'oneof' เป็นเท็จหรือไม่หากส่วนใดส่วนหนึ่งตรวจไม่พบ
Leonidas

1
คำขอบางส่วนจะไม่มีส่วนหัวทั้งหมด โดยเฉพาะการร้องขอ GET จะถูกส่งโดยเบราว์เซอร์และเมื่อไม่ได้รับการตอบรับอนุญาตที่ถูกต้องจะมีข้อผิดพลาดเกิดขึ้นกับ js ในขณะที่คำขอ POST คำขอ OPTIONS จะถูกส่งครั้งแรกด้วยส่วนหัว allow-method และหลังจากนั้นจะส่งคำขอ POST จริง
mcfedr

1
อ่าฉันเข้าใจแล้ว ขอบคุณ คุณเคยประสบปัญหาโดยไม่ใส่ res.send (200) ในนั้นถ้าวิธีการ req เป็น 'ตัวเลือก'?
Leonidas

ฉันไม่คิดว่าฉันได้ลองส่งสิ่งอื่นแล้วฉันจะนึกภาพการตอบสนองอื่น ๆ ที่จะทำให้เบราว์เซอร์ปฏิเสธคำขอว่าเป็นการ preflighting
mcfedr

ใช้งานได้อย่างมีเสน่ห์ฉันจะเพิ่มรายการโดเมนที่ได้รับอนุญาตเพื่อความปลอดภัยมากขึ้น
Sebastien H.

37

ติดตั้งโมดูล 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


2
TypeError: Cannot read property 'headers' of undefinedการตั้งค่าแอพพื้นฐานที่สุด
Oliver Dixon

คุณแน่ใจหรือว่ามีคำขอวัตถุ :)
codebased

33

ทำสิ่งนี้:

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();
});

20

การทดสอบเสร็จสิ้นด้วย 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();
});

2
ไฟล์ใดที่เราต้องเพิ่มบรรทัดนี้?
Shefalee Chaudhary

20

ก่อนอื่นเพียงติดตั้ง cors ในโครงการของคุณ ใช้เทอร์มินัล (พรอมต์คำสั่ง) และcdไปยังไดเรกทอรีโครงการของคุณและเรียกใช้คำสั่งด้านล่าง:

npm install cors --save

จากนั้นนำไฟล์ server.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();
});

สิ่งนี้ได้ผลสำหรับฉัน ..


4
คุณไม่ต้องการcorsถ้าคุณทำres.headerสิ่งนี้ corsเป็นห้องสมุดที่จัดการทุกอย่างให้คุณ ลบบรรทัดแรกและบรรทัดที่ 3 (ทุกอย่างด้วย AKA cors) และคุณจะพบว่ายังใช้งานได้
thisissami

heck ฉันค่อนข้างแน่ใจว่าสิ่งที่คุณต้องการจริงๆคือบรรทัดนี้res.header("Access-Control-Allow-Origin", "*");
71717

แต่โปรดจำไว้ว่าคุณกำลังลดความปลอดภัยลงด้วยการทำเช่นนั้น :)
thisissami

10

มันใช้งานได้ดีสำหรับฉันเพราะมันใช้งานง่ายในเส้นทางฉันใช้ meanjs และใช้งานได้ดีซาฟารีโครเมี่ยม ฯลฯ

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);

    });

10

ก่อนหน้านี้ฉันประสบปัญหานี้ดังนั้นฉันจึงอนุญาตให้ 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);

ลองนี้หลังจากติดตั้ง cors Cors ไม่ใช่หน้าที่
Rickin โคลิน

9

ในของindex.jsฉันฉันเพิ่ม:

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

2
ฉันควรจะแสดงความคิดเห็นว่าAccess-Control-Allow-Origin = *หมายความว่าคุณจะไม่สามารถที่จะส่งคุกกี้ไปยังเซิร์ฟเวอร์ที่พวกเขาจะได้รับการปฏิเสธจากนโยบาย ธ - แหล่งที่มา: developer.mozilla.org/en-US/docs/Web/HTTP/... ดังนั้นอย่าใช้สิ่งนี้หากคุณต้องการใช้คุกกี้
Eksapsy

7

หากคุณต้องการให้มันเป็นคอนโทรลเลอร์เฉพาะคุณสามารถใช้:

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


6

สามารถอ้างถึงรหัสด้านล่างสำหรับเดียวกัน ที่มา: 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
})

ฉันเห็นคำตอบมากมายและสิ่งนี้มีสิ่งที่เป็น importan ฉันพยายามใช้ส่วนนี้ของรหัสหลังจากการกำหนดค่าอื่น ๆ และมันใช้งานไม่ได้และด้วยเหตุผลบางอย่างฉันลองวางรหัสหลังจากแอปconst app = express();และใช้งานได้! ฉันคิดว่าเป็นสิ่งสำคัญที่จะพูดถึงมัน
rfcabal

4

โซลูชันที่ง่ายที่สุดของฉันด้วย Express 4.2.0 (แก้ไข: ดูเหมือนจะไม่ทำงานใน 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', ...)นั้นจะได้ผลเช่นกัน ...


3

คำตอบที่ง่ายที่สุดคือการใช้เพียงแพคเกจล

const cors = require('cors');

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

ที่จะช่วยให้ CORS ทั่วทั้งกระดาน หากคุณต้องการที่จะเรียนรู้วิธีการเปิดใช้งานโดยไม่ต้องโมดูลล ธ นอกทั้งหมดที่คุณต้องการจริงๆคือบางมิดเดิ้ลเอ็กซ์เพรสว่าชุดหัว 'การเข้าถึงการควบคุมอนุญาตให้-กำเนิด' นั่นเป็นขั้นต่ำที่คุณต้องอนุญาตให้ใช้โดเมนคำขอข้ามจากเบราว์เซอร์ไปยังเซิร์ฟเวอร์ของคุณ

app.options('*', (req, res) => {
  res.set('Access-Control-Allow-Origin', '*');
  res.send('ok');
});

app.use((req, res) => {
  res.set('Access-Control-Allow-Origin', '*');
});

2

การใช้ 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);
});

การอ้างอิง


2

ทำงานด้านล่างสำหรับฉันหวังว่ามันจะช่วยให้ใครบางคน!

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

app.use(cors({ origin: true }));

มีการอ้างอิงจากhttps://expressjs.com/th/resources/middleware/cors.html#configuring-cors


ไฟล์อะไรเข้าไปข้างใน? peanutbutter.js?
Andrew Koper

ไม่แน่ใจเกี่ยวกับ peanutbutter.js สำหรับฉันมันเป็น express.js โดยพื้นฐานแล้วควรเป็นไฟล์ที่คุณต้องการแอปด่วนของคุณเริ่มต้นและต้องมีไฟล์เส้นทาง
Vatsal Shah

1

ฉันพบว่ามันเป็นเรื่องง่ายมากที่จะทำเช่นนี้ด้วยแพคเกจคำขอ 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'));
});

1

ใน typescript ถ้าคุณต้องการใช้ node.js package 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;

สำหรับการใช้ไฟล์ app.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);

1
"ถ้าเซิร์ฟเวอร์เขียนด้วย typescript" - ไม่ใช่ คำถามบอกว่ามันเขียนใน CoffeeScript
เควนติน

1
@Quentin ฉันแค่ต้องการแสดงทางเลือกใน typesript โดยหวังว่าสิ่งนี้จะช่วยใครซักคน
เอาชนะ

1

นี่เป็นคำตอบที่แพทคุ้นเคยกับความแตกต่างที่ฉันจบด้วย res.sendStatus (200); แทนที่จะเป็นถัดไป ();

รหัสจะจับการร้องขอทั้งหมดของวิธีการประเภทตัวเลือกและส่งกลับการควบคุมการเข้าถึงส่วนหัว

app.options('/*', (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');
    res.sendStatus(200);
});

รหัสรับ CORS จากต้นกำเนิดทั้งหมดตามที่ร้องขอในคำถาม อย่างไรก็ตามควรแทนที่ * ด้วยต้นกำเนิดที่เฉพาะเจาะจงเช่นhttp: // localhost: 8080เพื่อป้องกันการใช้ในทางที่ผิด

เนื่องจากเราใช้ app.options-method แทน app.use-method เราไม่จำเป็นต้องทำการตรวจสอบนี้:

req.method === 'OPTIONS'

ซึ่งเราสามารถเห็นได้ในคำตอบอื่น ๆ

ผมพบคำตอบที่นี่: http://johnzhang.io/options-request-in-express


1

คุณสามารถใช้มิดเดิลแวร์ Express บล็อกโดเมนและวิธีการของคุณ

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", process.env.DOMAIN); // update to match the domain you will make the request from
  res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
  res.header(
    "Access-Control-Allow-Headers",
    "Origin, X-Requested-With, Content-Type, Accept"
  );
  next();
});

สิ่งนี้ช่วยฉันด้วยปัญหาของฉันขอบคุณ!
Fr0zen อย่างเป็นทางการ

0

เราสามารถหลีกเลี่ยง 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");
});

1
นี่ไม่ตอบคำถามที่ถาม
david.barkhuizen

0

ฉันใช้ขั้นตอนต่อไปนี้กับเว็บแอปของฉันและฉันประสบความสำเร็จ:

เพิ่มแพ็คเกจ cors ไปยัง express:

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.

0

วิธีที่ง่ายที่สุดคือติดตั้งโมดูล cors ในโครงการของคุณโดยใช้:

npm i --save cors

จากนั้นในไฟล์เซิร์ฟเวอร์ของคุณนำเข้าโดยใช้ข้อมูลต่อไปนี้:

import cors from 'cors';

จากนั้นใช้เป็นตัวกลางเช่นนี้

app.use(cors());

หวังว่านี่จะช่วยได้!


0

ถ้าฉันเป็นคุณ @OP ฉันจะเปลี่ยนกระบวนทัศน์การเขียนโปรแกรมของฉัน

สมมติว่าคุณกำลังทำให้ CORS เหล่านี้ถูกบล็อกเนื่องจากคุณทำการร้องขอไปยัง localhost หรือสิ่งที่คล้ายกัน

ในที่สุดหากคุณจะปรับใช้กับ optoins การผลิตเช่นGoogle Cloud PlatformหรือHerokuหรือคุณจะไม่ต้องกังวลเกี่ยวกับ CORS เช่นอนุญาตให้กำเนิดหรืออะไรก็ตามในการผลิต

ดังนั้นเมื่อทดสอบเซิร์ฟเวอร์เพียงแค่ใช้postmanและคุณจะไม่ได้รับ CORS บล็อกหลังจากนั้นปรับใช้เซิร์ฟเวอร์ของคุณแล้วทำงานกับลูกค้าของคุณ


0

/ * ก่อนอื่นและนี่อาจเป็นปัญหาในหมู่ผู้ที่หลงทางอยู่เช่นฉัน: อย่าลืมใช้ "แลมบ์ดา" >>>> "` "และไม่ใช่" '"ในการดึงของคุณวิธีการ ! * /

`` `การตอบสนอง const = รอการดึง (https://api.... );

/ plus ขอแนะนำบทความต่อไปนี้: https://developer.edamam.com/api/faq /


0

ง่ายยาก:

 let my_data = []
const promise = new Promise(async function (resolve, reject) {
    axios.post('https://cors-anywhere.herokuapp.com/https://maps.googleapis.com/maps/api/directions/json?origin=33.69057660000001,72.9782724&destination=33.691478,%2072.978594&key=AIzaSyApzbs5QDJOnEObdSBN_Cmln5ZWxx323vA'
        , { 'Origin': 'https://localhost:3000' })
        .then(function (response) {
            console.log(`axios response ${response.data}`)
            const my_data = response.data
            resolve(my_data)
        })
        .catch(function (error) {
            console.log(error)
            alert('connection error')
        })
})
promise.then(data => {
    console.log(JSON.stringify(data))
})

0

ลองนี่ในไฟล์ js หลักของคุณ:

app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header(
  "Access-Control-Allow-Headers",
  "Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method"
);
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, DELETE");
res.header("Allow", "GET, POST, OPTIONS, PUT, DELETE");
next();
});

วิธีนี้จะช่วยแก้ปัญหาของคุณได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.