Heim > Web-Frontend > js-Tutorial > Hauptteil

Ausführliche Erklärung zum Umgang mit CORS mithilfe von Node.js

青灯夜游
Freigeben: 2020-10-28 17:42:06
nach vorne
3771 Leute haben es durchsucht

Ausführliche Erklärung zum Umgang mit CORS mithilfe von Node.js

Empfehlung für ein Video-Tutorial: node js-Tutorial

Einführung

In diesem Artikel erfahren Sie, wie Sie CORS mit Express konfigurieren und die CORS-Middleware nach Bedarf anpassen.

Was ist CORS?

CORS ist die Abkürzung für „Cross-domain Resource Sharing“. Dabei handelt es sich um einen Mechanismus, der Anfragen nach Ressourcen auf einem Webserver zulässt oder einschränkt, je nachdem, wo die HTTP-Anfrage gestellt wird.

Diese Strategie wird verwendet, um einen bestimmten Webserver vor dem Zugriff anderer Websites oder Domänen zu schützen. Nur zugelassene Domänen können auf Dateien auf dem Server zugreifen, z. B. Stylesheets, Bilder oder Skripte.

Angenommen, Sie verwenden derzeit http://example.com/page1 und zitieren aus dem Bild http://image.com/myimage.jpg Das Bild ist nur verfügbar, wenn http://image.com die ursprungsübergreifende Freigabe mit http://example.com zulässt. http://example.com/page1,并且你引用的是来自 http://image.com/myimage.jpg 的图片,那么除非 http://image.com 允许与 http://example.com 进行跨域共享,否则将无法获取该图像。

每个 HTTP 请求头中都有一个名为 origin 的头。它定义了域请求的来源。可以用这个头的信息来限制引用你服务器上的资源。

默认来自任何其他来源的请求都会受到浏览器的限制。

例如当开发时如果用的是 React 或 Vue 这类的前端库,则前端应用将运行在 http://localhost:3000 上,同时,你的 Express 服务器可能正在其他端口上运行,例如 http://localhost:2020。这时就需要在这些服务器之间允许 CORS。

如果你在浏览器控制台中看到下图这类的错误。问题可能出在 CORS 限制上:

Ausführliche Erklärung zum Umgang mit CORS mithilfe von Node.js

如果我们需要提供公共 API 并希望控制对某些资源的访问和使用方式时,CORS 能够发挥很大的作用。

另外,如果想在其他网页上使用自己的 API 或文件,也可以简单地将 CORS 配置为允许自己引用,同时把其他人拒之门外。

用 Express 配置 CORS

首先创建一个新的项目,并创建目录结构,然后使用默认设置运行 npm init

$ mkdir myapp
$ cd myapp
$ npm init -y
Nach dem Login kopieren

接下来安装所需的模块。我们将使用 expresscors 中间件:

$ npm i --save express
$ npm i --save cors
Nach dem Login kopieren

然后,开始创建一个简单的有两个路由的 Web 程序,用来演示 CORS 的工作原理。

首先创建一个名为 index.js 的文件,用来充当 Web 服务器,并实现几个请求处理函数:

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

const app = express();

app.get('/', (req, res) => {
    res.json({
        message: 'Hello World'
    });
});

app.get('/:name', (req, res) => {
    let name = req.params.name;

    res.json({
        message: `Hello ${name}`
    });
});

app.listen(2020, () => {
    console.log('server is listening on port 2020');
});
Nach dem Login kopieren

运行服务器:

$ node index.js
Nach dem Login kopieren

访问 http://localhost:2020/ 服务器应该返回 JSON 消息:

{
  "message": "Hello World"
}
Nach dem Login kopieren

访问 http://localhost:2020/something 应该能够看到:

{
  "message": "Hello something"
}
Nach dem Login kopieren

启用所有CORS请求

如果想为所有的请求启用 CORS,可以在配置路由之前简单地使用 cors 中间件:

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

const app = express();

app.use(cors())

......
Nach dem Login kopieren

如果需要,这会允许在网络上的任何位置访问所有路由。所以在本例中,每个域都可以访问两条路由。

例如,如果我们的服务器在 http://www.example.com 上运行并提供诸如图片之类的内容,则我们允许 http://www.differentdomain.com 之类的其他域从 http://www.example.com 进行引。

因此 http://www.differentdomain.com 上的网页可以将我们的域用作图像的来源:

<img  alt="Ausführliche Erklärung zum Umgang mit CORS mithilfe von Node.js" >
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

为单个路由启用 CORS

如果只需要其中某一个路由,可以在某个路由中将 cors 配置为中间件:

app.get('/', cors(), (req, res) => {
    res.json({
        message: 'Hello World'
    });
});
Nach dem Login kopieren

这会允许任何域访问特定的路由。在当前的情况下,其他域都只能访问 / 路由。仅在与 API(在本例中为http://localhost:2020)的相同域中发起的请求才能访问 /:name 路由。

如果尝试另一个来源发送请求到 / 路径将会成功,并且会收到 Hello World 作为响应:

fetch('http://localhost:2020/')
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(err => console.error(err));
Nach dem Login kopieren

运行上面的代码,会看到来自服务器的响应已成功输出到控制台:

{
    message: 'Hello World'
}
Nach dem Login kopieren

如果访问除根路径以外的其他路径,例如  http://localhost:2020/namehttp://localhost:2020/img/cat.png,则此请求将会被浏览器阻止:

fetch('http://localhost:2020/name/janith')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));
Nach dem Login kopieren

如果在其他 Web 应用中运行代码,应该看到以下错误:

Ausführliche Erklärung zum Umgang mit CORS mithilfe von Node.js

用选项配置CORS

还可以用自定义选项来配置 CORS。可以根据需要配置允许的 HTTP 方法,例如 GETPOST

Jeder HTTP-Anfrageheader hat einen Header mit dem Namen origin. Es definiert den Ursprung von Domänenanfragen. Mithilfe dieser Header-Informationen können Sie Verweise auf Ressourcen auf Ihrem Server einschränken.

Anfragen von anderen Quellen werden standardmäßig vom Browser eingeschränkt. 🎜🎜Wenn Sie beispielsweise bei der Entwicklung eine Front-End-Bibliothek wie React oder Vue verwenden, wird die Front-End-Anwendung gleichzeitig auf http://localhost:3000 ausgeführt Der Express-Server wird möglicherweise auf einem anderen Port ausgeführt, z. B. http://localhost:2020. Dann müssen Sie CORS zwischen diesen Servern zulassen. 🎜🎜Wenn in Ihrer Browserkonsole ein Fehler wie der folgende angezeigt wird. Das Problem kann durch CORS-Einschränkungen verursacht werden: 🎜🎜 1 .png🎜🎜CORS kann eine große Rolle spielen, wenn wir eine öffentliche API bereitstellen müssen und steuern möchten, wie auf bestimmte Ressourcen zugegriffen und diese verwendet werden. 🎜🎜Wenn Sie außerdem Ihre eigene API oder Dateien auf anderen Webseiten verwenden möchten, können Sie CORS einfach so konfigurieren, dass auf Sie selbst verwiesen werden kann, während andere davon ferngehalten werden. 🎜🎜CORS mit Express konfigurieren🎜🎜Erstellen Sie zunächst ein neues Projekt und erstellen Sie die Verzeichnisstruktur. Führen Sie dann npm init mit den Standardeinstellungen aus: 🎜
var corsOptions = {
    origin: 'http://localhost:8080',
    optionsSuccessStatus: 200 // For legacy browser support
}

app.use(cors(corsOptions));
Nach dem Login kopieren
Nach dem Login kopieren
🎜Als nächstes installieren Sie die erforderlichen Module. Wir werden die Middleware express und cors verwenden: 🎜
//
fetch('http://localhost:2020/')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));

//
fetch('http://localhost:2020/name/janith')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));
Nach dem Login kopieren
Nach dem Login kopieren
🎜 Dann beginnen wir mit der Erstellung einer einfachen Webanwendung mit zwei Routen, um zu demonstrieren, wie CORS funktioniert. 🎜🎜Erstellen Sie zunächst eine Datei mit dem Namen index.js, die als Webserver fungiert und mehrere Funktionen zur Anforderungsverarbeitung implementiert: 🎜
var corsOptions = {
    origin: 'http://localhost:8080',
    optionsSuccessStatus: 200 // 对于旧版浏览器的支持
    methods: "GET, PUT"
}

app.use(cors(corsOptions));
Nach dem Login kopieren
Nach dem Login kopieren
🎜Führen Sie den Server aus: 🎜
fetch('http://localhost:2020', {
  method: 'POST',
  body: JSON.stringify({name: "janith"}),
})
.then(response => response.json())
.then(data => console.log(data))
.catch(err => console.error(err));
Nach dem Login kopieren
Nach dem Login kopieren
🎜Besuchen Sie http://localhost:2020/ code> The Der Server sollte eine JSON-Nachricht zurückgeben: 🎜<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">const allowlist = ['http://something.com', 'http://example.com'];     const corsOptionsDelegate = (req, callback) =&gt; {     let corsOptions;     let isDomainAllowed = whitelist.indexOf(req.header('Origin')) !== -1;     let isExtensionAllowed = req.path.endsWith('.jpg');     if (isDomainAllowed &amp;&amp; isExtensionAllowed) {         // 为此请求启用 CORS         corsOptions = { origin: true }     } else {         // 为此请求禁用 CORS         corsOptions = { origin: false }     }     callback(null, corsOptions) } app.use(cors(corsOptionsDelegate));</pre><div class="contentsignin">Nach dem Login kopieren</div></div><div class="contentsignin">Nach dem Login kopieren</div></div>🎜Besuchen Sie <code>http://localhost:2020/something und Sie sollten Folgendes sehen: 🎜
<img  alt="Ausführliche Erklärung zum Umgang mit CORS mithilfe von Node.js" >
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
🎜Alle CORS-Anfragen aktivieren🎜🎜Wenn Sie CORS für alle Anfragen aktivieren möchten , können Sie einfach die Middleware cors verwenden, bevor Sie die Routen konfigurieren: 🎜
<img  alt="Ausführliche Erklärung zum Umgang mit CORS mithilfe von Node.js" >
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
🎜Dies ermöglicht bei Bedarf den Zugriff auf alle Routen von überall im Netzwerk. In diesem Beispiel hat also jede Domäne Zugriff auf zwei Routen. 🎜🎜Wenn unser Server beispielsweise auf http://www.example.com läuft und Inhalte wie Bilder bereitstellt, erlauben wir http://www.differentdomain com werden von http://www.example.com referenziert. 🎜🎜So können Webseiten unter http://www.differentdomain.com unsere Domain als Quelle für Bilder verwenden: 🎜
var corsOptions = {
    origin: function (origin, callback) {
        // 从数据库加载允许的来源列表
        // 例如:origins = ['http://example.com', 'http//something.com']
        database.loadOrigins((error, origins) => {
            callback(error, origins);
        });
    }
}

app.use(cors(corsOptions));
Nach dem Login kopieren
Nach dem Login kopieren
🎜CORS für einzelne Routen aktivieren🎜🎜Wenn nur eine davon benötigt wird, cors kann als Middleware in einer Route konfiguriert werden: 🎜rrreee🎜Dadurch kann jede Domain auf die spezifische Route zugreifen. In der aktuellen Situation können andere Domänen nur auf die Route / zugreifen. Auf die Route /:name kann nur von Anforderungen zugegriffen werden, die in derselben Domäne wie die API initiiert wurden (in diesem Fall http://localhost:2020). 🎜🎜Wenn Sie versuchen, von einem anderen Ursprung aus eine Anfrage an den Pfad / zu senden, wird dies erfolgreich sein und Sie erhalten als Antwort Hello World: 🎜rrreee🎜Führen Sie den obigen Code aus und Sie werden es tun siehe Die Antwort vom Server wurde erfolgreich an die Konsole ausgegeben: 🎜rrreee🎜 Beim Zugriff auf einen anderen Pfad als den Root-Pfad, z. B. http://localhost:2020/name oder http: //localhost: 2020/img/cat.png, dann wird diese Anfrage vom Browser blockiert: 🎜rrreee🎜Wenn Sie den Code in anderen Webanwendungen ausführen, sollte die folgende Fehlermeldung angezeigt werden: 🎜🎜Ausführliche Erklärung zum Umgang mit CORS mithilfe von Node.js🎜🎜CORS mit Optionen konfigurieren🎜 🎜Sie können die Optionen auch anpassen, um CORS zu konfigurieren. Zulässige HTTP-Methoden wie GET und POST können nach Bedarf konfiguriert werden. 🎜🎜So erlauben Sie den Zugriff auf eine einzelne Domain über die CORS-Option: 🎜
var corsOptions = {
    origin: 'http://localhost:8080',
    optionsSuccessStatus: 200 // For legacy browser support
}

app.use(cors(corsOptions));
Nach dem Login kopieren
Nach dem Login kopieren

如果你在源中配置域名-服务器将允许来自已配置域的CORS。因此,在我们的例子中,可以从 http://localhost:8080 访问该API,并禁止其他域使用。

如果发送一个 GET 请求,则任何路径都应该可以访问,因为这些选项是在应用在程序级别上的。

运行下面的代码将请求从 http://localhost:8080 发送到 http://localhost:2020

//
fetch('http://localhost:2020/')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));

//
fetch('http://localhost:2020/name/janith')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));
Nach dem Login kopieren
Nach dem Login kopieren

可以看到被允许从该程序和域中获取信息。

还可以根据需要配置允许的 HTTP 方法:

var corsOptions = {
    origin: 'http://localhost:8080',
    optionsSuccessStatus: 200 // 对于旧版浏览器的支持
    methods: "GET, PUT"
}

app.use(cors(corsOptions));
Nach dem Login kopieren
Nach dem Login kopieren

如果从 http://localhost:8080 发送POST请求,则浏览器将会阻止它,因为仅支持 GET 和 PUT:

fetch('http://localhost:2020', {
  method: 'POST',
  body: JSON.stringify({name: "janith"}),
})
.then(response => response.json())
.then(data => console.log(data))
.catch(err => console.error(err));
Nach dem Login kopieren
Nach dem Login kopieren

用函数配置动态 CORS 源

如果配置不满足你的要求,也可以创建函数来定制 CORS。

例如假设要允许 http://something.com 和 http://example.com 对 .jpg  文件进行CORS共享:

const allowlist = ['http://something.com', 'http://example.com'];

    const corsOptionsDelegate = (req, callback) => {
    let corsOptions;

    let isDomainAllowed = whitelist.indexOf(req.header('Origin')) !== -1;
    let isExtensionAllowed = req.path.endsWith('.jpg');

    if (isDomainAllowed && isExtensionAllowed) {
        // 为此请求启用 CORS
        corsOptions = { origin: true }
    } else {
        // 为此请求禁用 CORS
        corsOptions = { origin: false }
    }
    callback(null, corsOptions)
}

app.use(cors(corsOptionsDelegate));
Nach dem Login kopieren
Nach dem Login kopieren

回调函数接受两个参数,第一个是传递 null 的错误,第二个是传递  { origin: false } 的选项。第二个参数可以是用 Express 的 request 对象构造的更多选项。

所以 http://something.comhttp://example.com 上的 Web 应用将能够按照自定义配置从服务器引用扩展名为 .jpg 的图片。

这样可以成功引用资源文件:

<img  alt="Ausführliche Erklärung zum Umgang mit CORS mithilfe von Node.js" >
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

但是下面的文件将会被阻止:

<img  alt="Ausführliche Erklärung zum Umgang mit CORS mithilfe von Node.js" >
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

从数据源加载允许的来源列表作

还可以用保存在数据库中的白名单列表或任何一种数据源来允许 CORS:

var corsOptions = {
    origin: function (origin, callback) {
        // 从数据库加载允许的来源列表
        // 例如:origins = ['http://example.com', 'http//something.com']
        database.loadOrigins((error, origins) => {
            callback(error, origins);
        });
    }
}

app.use(cors(corsOptions));
Nach dem Login kopieren
Nach dem Login kopieren

原文:https://stackabuse.com/handling-cors-with-node-js/

作者:Janith Kasun

更多编程相关知识,可访问:编程教学!!

Das obige ist der detaillierte Inhalt vonAusführliche Erklärung zum Umgang mit CORS mithilfe von Node.js. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:segmentfault.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage