كيفية السماح بطلبات عبر المواقع من خلال إعداد CORS
عادةً ما يمكن لتطبيق JavaScript قيد التشغيل في المستعرض الوصول فقط إلى موارد HTTP من نفس المجال (الأصل) الذي يخدمهم.
يتم دائمًا تحميل الصور أو البرامج النصية / الأنماط من نفس الأصل. أيضا ، تحميل خطوط الويب باستخدام@font-face
تعيين سياسة "نفس الأصل" افتراضيًا. وبالمثل مع الأشياء الأخرى الأقل شيوعًا (مثل زخارف WebGL وdrawImage
الموارد التي تم تحميلها في Canvas API).
ومع ذلك ، ستفشل مكالمات XHR و Fetch إلى خادم خارجي تابع لجهة خارجية. هذا ما لم ينفذ خادم الطرف الثالث آلية تسمح بإجراء الاتصال وتنزيل الموارد المطلوبة واستخدامها.
هذه الآلية تسمىكورسوتبادل الموارد عبر المنشأ.
أحد الأشياء المهمة جدًا التي تحتاج إلى CORS هووحدات ES، تم طرحه مؤخرًا في المتصفحات الحديثة.
إذا لم تقم بإعداد سياسة CORSعلى الخادمالذي يسمح لها بخدمة أصول الطرف الثالث ، فسيفشل الطلب.
مثال على الجلب:
مثال XHR:
يفشل مورد متعدد الأصول إذا كان:
- إلى مختلفنطاق
- إلى مختلفالمجال الفرعي
- إلى مختلفميناء
- إلى مختلفبروتوكول
CORS موجود لأمنك ، لمنع المستخدمين المؤذيين من استغلال أي منصة ويب تصادف أنك تستخدمها.
إذا كنت تتحكم في كل من الخادموالعميل ، فأنت تعلم أن كلا الطرفين جدير بالثقة ، وبالتالي لديك سبب وجيه للسماح بمشاركة الموارد.
كيف؟
يعتمد ذلك على مكدس جانب الخادم الخاص بك.
دعم المتصفح
جيد جدًا (الكل بشكل أساسي باستثناء IE <10):
مثال مع Express
إذا كنت تستخدم Node.js و Express كإطار عمل ، فاستخدم ملحقحزمة البرامج الوسيطة CORS.
فيما يلي تطبيق بسيط لخادم Express Node.js:
const express = require('express')
const app = express()
app.get(’/without-cors’, (req, res, next) => {
res.json({ msg: ‘😞 no CORS, no party!’ })
})
const server = app.listen(3000, () => {
console.log(‘Listening on port %s’, server.address().port)
})
إذا ضربت/without-cors
مع طلب جلب من أصل مختلف ، فسيؤدي ذلك إلى إثارة مشكلة CORS.
كل ما عليك فعله لجعل الأشياء تعمل بسلاسة ، هو أن تطلبcors
الحزمة المرتبطة أعلاه ، وقم بتمريرها كوظيفة وسيطة إلى معالج طلب نقطة النهاية:
const express = require('express')
const cors = require('cors')
const app = express()
app.get(’/with-cors’, cors(), (req, res, next) => {
res.json({ msg: ‘WHOAH with CORS it works! 🔝 🎉’ })
})
/* the rest of the app */
لقد قدمت مثالًا بسيطًا لـ Glitch ، إليك رمزه:https://glitch.com/edit/#!/flavio-cors-client.
هذا هو خادم Node.js Express:https://glitch.com/edit/#!/flaviocopes-cors-example-express
لاحظ كيف أن الطلب الذي فشل لأن الخادم لا يعالج رؤوس CORS بشكل صحيح ، لا يزال مستلمًا. كما ترى في لوحة الشبكة ، حيث يمكنك رؤية رسالة أرسلها الخادم:
السماح بأصول محددة فقط
ومع ذلك ، فإن هذا المثال به مشكلة: سيتم قبول أي طلب من قبل الخادم باعتباره أصل مشترك.
كما ترى في لوحة الشبكة ، فإن الطلب الذي تم تمريره له رأس استجابةaccess-control-allow-origin: *
:
تحتاج إلى تكوين الخادم للسماح لمصدر واحد فقط بالخدمة ، وحظر كل الآخرين.
باستخدام نفس الشيءcors
مكتبة العقدة ، وإليك كيفية القيام بذلك:
const cors = require('cors')
const corsOptions = {
origin: ‘https://yourdomain.com’,
}
app.get(’/products/:id’, cors(corsOptions), (req, res, next) => {
//…
})
يمكنك تقديم المزيد أيضًا:
const whitelist = ['http://example1.com', 'http://example2.com']
const corsOptions = {
origin: function (origin, callback) {
if (whitelist.indexOf(origin) !== -1) {
callback(null, true)
} else {
callback(new Error('Not allowed by CORS'))
}
},
}
الاختبار المبدئي
هناك بعض الطلبات التي يتم التعامل معها بطريقة "بسيطة". الجميعGET
الطلبات تنتمي إلى هذه المجموعة.
أيضابعض POST
وHEAD
الطلبات تفعل كذلك.
POST
الطلبات موجودة أيضًا في هذه المجموعة ، إذا كانت تفي بمتطلبات استخدام نوع المحتوى
application/x-www-form-urlencoded
multipart/form-data
text/plain
يجب أن تمر جميع الطلبات الأخرى خلال مرحلة الموافقة المسبقة ، والتي تسمى الاختبار المبدئي. يقوم المستعرض بذلك لتحديد ما إذا كان لديه الإذن بتنفيذ إجراء ما ، عن طريق إصدار ملفOPTIONS
طلب.
يحتوي طلب الاختبار المبدئي على عدد قليل من الرؤوس التي سيستخدمها الخادم للتحقق من الأذونات (تم حذف الحقول غير ذات الصلة):
OPTIONS /the/resource/you/request
Access-Control-Request-Method: POST
Access-Control-Request-Headers: origin, x-requested-with, accept
Origin: https://your-origin.comThe server will respond with something like this (irrelevant fields omitted):
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://your-origin.com
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETEWe checked for POST, but the server tells us we can also issue other HTTP request types for that particular resource.
Following the Node.js Express example above, the server must also handle the OPTIONS request:
var express = require('express')
var cors = require('cors')
var app = express()
//allow OPTIONS on just one resource
app.options(’/the/resource/you/request’, cors())
//allow OPTIONS on all resources
app.options(’*’, cors())
Download my free Express.js Handbook
More express tutorials:
- Express, a popular Node.js Framework
- Retrieve the GET query string parameters using Express
- Validating input in Express using express-validator
- Express Templates
- Serving Static Assets with Express
- Send a JSON response using Express
- Express Sessions
- Send a response using Express
- Send files using Express
- Sanitizing input in Express using express-validator
- Routing in Express
- An Express HTTPS server with a self-signed certificate
- Express, Request Parameters
- Retrieve the POST query parameters using Express
- Handling redirects with Express
- Express Middleware
- Setup Let's Encrypt for Express
- Work with HTTP headers in Express
- Handling forms in Express
- Handling file uploads in forms using Express
- Handling CORS in Express
- Manage Cookies with Express