获取 & CORS

摘要: 在本教程中,您将探索 CORS(跨源资源共享)以及如何配置 Web 服务器以启用 CORS,以便一个源可以获取数据。

什么是源

源是指三个组件的唯一组合

  • 协议(方案): URL 中指定的协议,例如 HTTPHTTPSFTPS 等。
  • 域名(主机): 这是域名或 IP 地址,例如 javascripttutorial.net127.0.0.1
  • 端口: 这是用于与 Web 服务器通信的端口号。如果您没有指定端口,将使用协议的默认端口,例如,HTTPS 的端口 443HTTP 的端口 80

例如,https://tutorial.javascript.ac.cn/api/ 是一个源,其中

  • HTTPS 是协议。
  • www.javascriptttorial.net 是域名。
  • 443HTTPS 协议的默认端口。

https://api.javascripttutorial.net/ 是一个不同的源,因为域名 api.javascripttutorial.net 与域名 www.javascripttutorial.net 不同。

源很重要,因为 Web 浏览器使用它来强制执行称为 CORS 的安全策略。

什么是 CORS

CORS(跨源资源共享)是 Web 浏览器的安全功能,它可以防止一个源向另一个源发出未经授权的请求。

浏览器允许网站向其自己的源发出 HTTP 请求。但是,如果该网站尝试请求不同的源(跨源),则浏览器会默认阻止此操作,以防止诸如 跨站点脚本 (XSS) 攻击 之类的安全风险。

让我们看一个示例,以更好地了解 CORS 的工作原理。

设置一个简单的 Web 服务器

我们将在 Node.js 中设置一个简单的 Express Web 服务器。

步骤 1. 创建一个新目录来存储项目文件

mkdir webserver
cd webserverCode language: JavaScript (javascript)

步骤 2. 通过在终端上运行 npm init 命令来初始化项目

npm init --yesCode language: JavaScript (javascript)

此命令将在项目目录中创建 package.json 文件。

步骤 3. 安装 express

npm install expressCode language: JavaScript (javascript)

步骤 4. 通过添加 type : "module" 来配置 package.json

"type": "module"Code language: JavaScript (javascript)

这将允许您在 Node.js 项目中使用 ES6 模块

并修改 script 部分

"scripts": {
    "start": "node index.js"
}Code language: JavaScript (javascript)

通过修改 scripts 部分,您可以在终端中执行 npm start 命令来运行 index.js 文件

步骤 5. 使用以下代码创建一个名为 index.js 的新文件

import express from 'express';
const app = express();

app.get('/', (req, res) => {
  res.send('Hello, World!');
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});Code language: JavaScript (javascript)

index.js 文件中,我们创建一个 Express Web 服务器,该服务器接受对路由 http://localhost:3000/GET 请求并返回 'Hello, World!' 消息。

步骤 6. 通过在终端中运行以下命令来启动 Web 服务器

npm start

步骤 7. 在 Web 浏览器中打开 http://localhost:3000/,您将看到 JSON 响应

{
  "message": "Hello, World!"
}Code language: JavaScript (javascript)

创建 JavaScript 应用程序

我们将创建一个简单的 JavaScript 应用程序,该应用程序将使用 fetch() 方法调用 API 端点 http://localhost:3000/

步骤 1. 创建一个新目录来存储 JavaScript 应用程序文件

mkdir app
cd app

步骤 2. 创建一个 index.html 文件

<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Fetch API - CORS</title>
    </head>

    <body>
        <button id="btn">Fetch</button>
        <p id="message"></p>
        <script src="app.js"></script>
    </body>

</html>Code language: HTML, XML (xml)

index.html 文件包括同一目录内的 app.js

步骤 3. 在项目目录中创建一个 app.js 文件

const btn = document.getElementById('btn');
const messageElem = document.getElementById('message');

btn.addEventListener('click', async () => {
  // reset the message
  messageElem.innerHTML = '';
  try {
    // call the API
    const response = await fetch('http://localhost:3000/');
    const data = await response.json();

    // update the message
    messageElem.innerHTML = data.message;
  } catch (err) {
    messageElem.innerHTML = err.message;
  }
});Code language: JavaScript (javascript)

步骤 4. 打开 index.html(使用 VS code 上的实时服务器扩展程序)并单击“获取”按钮,您将看到该消息

Failed to fetchCode language: JavaScript (javascript)

当您打开控制台窗口时,您将看到以下错误消息

Access to fetch at 'http://localhost:3000/' from origin 'http://127.0.0.1:5501' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.Code language: JavaScript (javascript)

原因是我们从源 http://127.0.0.1:5501 向源 http://localhost:3000/ 上的服务器发出了 HTTP 请求,浏览器阻止了它。

在 Web 服务器上启用 CORS

步骤 1. 打开终端并在 Node.js 项目中安装 cors

npm install corsCode language: JavaScript (javascript)

步骤 2. 修改 index.js 文件以允许来自所有源的 CORS

import express from 'express';
import cors from 'cors';

const app = express();

app.use(cors());

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

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});Code language: JavaScript (javascript)

它的工作原理。

首先,从 cors 包中导入 cors 函数

import cors from 'cors';Code language: JavaScript (javascript)

其次,调用 cors() 函数并将它的返回值传递给 app.use() 方法

app.use(cors());Code language: JavaScript (javascript)

这行代码指示 Express Web 服务器将以下条目添加到 HTTP 响应的标头中,这允许从任何源调用 API 端点

Access-Control-Allow-Origin: *Code language: JavaScript (javascript)

星号 (*) 表示任何源。

步骤 3. 通过停止 Web 服务器(按 Ctrl-C)并再次启动它来重新启动 Web 服务器

npm start

步骤 4. 单击 JavaScript 应用程序上的“获取”按钮。您将在 Web 浏览器中看到 Hello, World! 消息

Hello, World!Code language: JavaScript (javascript)

如果您检查 HTTP 响应的标头,您将看到以下条目

Access-Control-Allow-Origin: *Code language: JavaScript (javascript)

请注意,您可以通过将 http://127.0.0.1:5501 添加到 cors() 函数中来配置 Web 服务器以允许来自特定源的 CORS

// ...

app.use(
  cors({
    origin: 'http://127.0.0.1:5501',
  })
);
//  ...Code language: JavaScript (javascript)

请注意,源没有尾部斜杠 (/),因为浏览器发送的源可能不包含它。

在这种情况下,Web 服务器将在 HTTP 响应的标头中添加以下条目

Access-Control-Allow-Origin: http://127.0.0.1:5501/Code language: JavaScript (javascript)

下载项目源代码

单击此处下载项目源代码

解压缩 zip 文件后,您将看到两个目录

  • webserver
  • app

要启动 Web 服务器,您需要

首先,导航到 webserver 目录

cd webserver

其次,运行命令 npm install 来安装依赖项

npm install

第三,启动 Web 服务器

npm start

总结

  • 源由三个组件的组合定义:域名、协议和端口。
  • CORS(跨源资源共享)是内置于 Web 浏览器中的安全功能,默认情况下,它可以防止一个源向不同的源发出请求。
  • 要允许来自任何源的请求,请配置您的 Web 服务器以在其 HTTP 响应中包含标头 Access-Control-Allow-Origin: *
本教程对您有帮助吗?