javascript - لا يوجد 'Access-Control-Allow-Origin' في تطبيق react express docker
أنا أستخدم Docker لتشغيل تطبيق React للواجهة الأمامية وAPI باستخدام Node/Express. تطبيق React يعمل على localhost:3000 وAPI يعمل على localhost:9000. كلاهما تطبيقات كاملة وفعالة. ومع ذلك، عندما أحاول إجراء استدعاء REST من تطبيق React إلى http://localhost:9000/api/whatever، أحصل على الخطأ التالي
XMLHttpRequest cannot load http://localhost:9000/api/schedule. No
Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:3000' is therefore not allowed access.`
هذا هو ملف server.js الخاص بي لواجهة برمجة التطبيقات الخاصة بي باستخدام Express:
const express = require('express');
const port = process.env.PORT || 9000;
const app = express();
require('./app/routes')(app);
app.use(function(req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
app.listen(port, () => {
console.log('listening on port : ' + port);
})
لست متأكدًا مما أفتقده هنا.
علامة تبويب شبكة كروم :
Request URL:http://localhost:9000/api/schedule
Request Method:GET
Status Code:200 OK
Remote Address:[::1]:9000
Response Headers
view source
Connection:keep-alive
Content-Length:86
Content-Type:application/json; charset=utf-8
Date:Mon, 10 Apr 2017 04:40:06 GMT
ETag:W/"56-l2wi6AdD2GGTOMvRjRYO96YmR0w"
X-Powered-By:Express
Request Headers
view source
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Host:localhost:9000
Origin:http://localhost:3000
Referer:http://localhost:3000/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
الإجابة رقم 1
لقد تمكنت من فعل هذا من قبل باستخدام التكوين التالي:
app.use((req, res, next) => {
const origin = req.get('origin');
// TODO Add origin validation
res.header('Access-Control-Allow-Origin', origin);
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization, Cache-Control, Pragma');
// intercept OPTIONS method
if (req.method === 'OPTIONS') {
res.sendStatus(204);
} else {
next();
}
});
كما ترى في حالتي، كنت أسمح بمزيد من الأساليب أكثر من أسلوب GET فقط وأضفت رؤوسًا مسموح بها إضافية (مثل رأس Authorization الذي كنت بحاجة إليه في هذه الحالة)، لاحظ أنه في حالتك قمت بتحديد X-Requested-With وContent-Type فقط، لكن قد تحتاج أيضًا إلى رأس Origin إذا كنت تريد التحقق من الأصل.
أنا أيضًا أقوم باعتراض طلب OPTIONS لتجنب إرسال بيانات إضافية في تلك الحالة.
