Node.js를 사용하여 CORS를 처리하는 방법에 대한 자세한 설명

青灯夜游
풀어 주다: 2020-10-28 17:42:06
앞으로
3766명이 탐색했습니다.

Node.js를 사용하여 CORS를 처리하는 방법에 대한 자세한 설명

비디오 튜토리얼 권장 사항: node js tutorial

소개

이 기사에서는 Express로 CORS를 구성하고 필요에 따라 CORS 미들웨어를 사용자 정의하는 방법을 학습합니다.

CORS란 무엇입니까

CORS는 "Cross-domain Resource Sharing"의 약어입니다. HTTP 요청이 이루어진 위치에 따라 웹 서버의 리소스 요청을 허용하거나 제한하는 메커니즘입니다.

이 전략은 다른 웹사이트나 도메인의 액세스로부터 특정 웹 서버를 보호하는 데 사용됩니다. 허용된 도메인만 스타일시트, 이미지, 스크립트 등 서버의 파일에 액세스할 수 있습니다.

현재 http://example.com/page1을 사용하고 있고 http://image.com/myimage.jpg 이미지에서 인용하고 있다고 가정해 보겠습니다. http://image.comhttp://example.com과의 출처 간 공유를 허용하지 않으면 이미지를 사용할 수 없습니다. 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 限制上:

Node.js를 사용하여 CORS를 처리하는 방법에 대한 자세한 설명

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

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

用 Express 配置 CORS

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

$ mkdir myapp
$ cd myapp
$ npm init -y
로그인 후 복사

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

$ npm i --save express
$ npm i --save cors
로그인 후 복사

然后,开始创建一个简单的有两个路由的 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');
});
로그인 후 복사

运行服务器:

$ node index.js
로그인 후 복사

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

{
  "message": "Hello World"
}
로그인 후 복사

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

{
  "message": "Hello something"
}
로그인 후 복사

启用所有CORS请求

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

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

const app = express();

app.use(cors())

......
로그인 후 복사

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

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

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

<img  alt="Node.js를 사용하여 CORS를 처리하는 방법에 대한 자세한 설명" >
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

为单个路由启用 CORS

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

app.get('/', cors(), (req, res) => {
    res.json({
        message: 'Hello World'
    });
});
로그인 후 복사

这会允许任何域访问特定的路由。在当前的情况下,其他域都只能访问 / 路由。仅在与 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));
로그인 후 복사

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

{
    message: 'Hello World'
}
로그인 후 복사

如果访问除根路径以外的其他路径,例如  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));
로그인 후 복사

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

Node.js를 사용하여 CORS를 처리하는 방법에 대한 자세한 설명

用选项配置CORS

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

모든 HTTP 요청 헤더에는 origin이라는 헤더가 있습니다. 도메인 요청의 출처를 정의합니다. 이 헤더 정보를 사용하여 서버의 리소스에 대한 참조를 제한할 수 있습니다.

다른 소스의 요청은 기본적으로 브라우저에 의해 제한됩니다. 🎜🎜예를 들어 개발 시 React나 Vue와 같은 프런트엔드 라이브러리를 사용한다면 프런트엔드 애플리케이션은 http://localhost:3000에서 동시에 실행됩니다. Express 서버는 http://localhost:2020와 같은 포트에서 실행될 수 있습니다. 그런 다음 이러한 서버 간에 CORS를 허용해야 합니다. 🎜🎜브라우저 콘솔에 아래와 같은 오류가 표시되는 경우. CORS 제한으로 인해 문제가 발생할 수 있습니다. 🎜🎜 1 .png🎜🎜CORS는 공개 API를 제공해야 하고 특정 리소스에 액세스하고 사용하는 방법을 제어하려는 경우 큰 역할을 할 수 있습니다. 🎜🎜또한 다른 웹 페이지에서 자신의 API나 파일을 사용하려는 경우 다른 웹 페이지는 제외하고 자신만 참조할 수 있도록 CORS를 구성하면 됩니다. 🎜🎜Express로 CORS 구성🎜🎜먼저 새 프로젝트를 만들고 디렉터리 구조를 만든 다음 기본 설정으로 npm init를 실행하세요. 🎜
var corsOptions = {
    origin: 'http://localhost:8080',
    optionsSuccessStatus: 200 // For legacy browser support
}

app.use(cors(corsOptions));
로그인 후 복사
로그인 후 복사
🎜다음으로 필요한 모듈을 설치하세요. expresscors 미들웨어를 사용하겠습니다. 🎜
//
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));
로그인 후 복사
로그인 후 복사
🎜 그런 다음 CORS 작동 방식을 보여주기 위한 두 가지 경로가 있는 간단한 웹 애플리케이션 만들기를 시작합니다. 🎜🎜먼저 웹 서버 역할을 할 index.js라는 파일을 만들고 여러 요청 처리 기능을 구현하세요. 🎜
var corsOptions = {
    origin: 'http://localhost:8080',
    optionsSuccessStatus: 200 // 对于旧版浏览器的支持
    methods: "GET, PUT"
}

app.use(cors(corsOptions));
로그인 후 복사
로그인 후 복사
🎜서버 실행: 🎜
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));
로그인 후 복사
로그인 후 복사
🎜http://localhost:2020/를 방문하세요. 서버는 JSON 메시지를 반환해야 합니다: 🎜
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));
로그인 후 복사
로그인 후 복사
🎜 http://localhost:2020/something을 방문하면 다음이 표시됩니다: 🎜
<img  alt="Node.js를 사용하여 CORS를 처리하는 방법에 대한 자세한 설명" >
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
🎜모든 CORS 요청 활성화🎜🎜모든 요청에 ​​대해 CORS를 활성화하려는 경우 , 경로를 구성하기 전에 간단히 cors 미들웨어를 사용할 수 있습니다. 🎜
<img  alt="Node.js를 사용하여 CORS를 처리하는 방법에 대한 자세한 설명" >
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
🎜 이렇게 하면 원하는 경우 네트워크의 어느 곳에서나 모든 경로에 액세스할 수 있습니다. 따라서 이 예에서는 각 도메인이 두 개의 경로에 액세스할 수 있습니다. 🎜🎜예를 들어, 당사 서버가 http://www.example.com에서 실행되고 이미지와 같은 콘텐츠를 제공하는 경우 http://www.다른 도메인과 같은 다른 도메인도 허용됩니다. comhttp://www.example.com에서 참조됩니다. 🎜🎜그래서 http://www.다른도메인.com의 웹페이지는 우리 도메인을 이미지 소스로 사용할 수 있습니다: 🎜
var corsOptions = {
    origin: function (origin, callback) {
        // 从数据库加载允许的来源列表
        // 例如:origins = ['http://example.com', 'http//something.com']
        database.loadOrigins((error, origins) => {
            callback(error, origins);
        });
    }
}

app.use(cors(corsOptions));
로그인 후 복사
로그인 후 복사
🎜개별 경로에 대해 CORS 활성화🎜🎜그 중 하나만 필요한 경우, cors는 경로에서 미들웨어로 구성될 수 있습니다: 🎜rrreee🎜이렇게 하면 모든 도메인이 특정 경로에 액세스할 수 있습니다. 현재 상황에서는 다른 도메인은 / 경로에만 액세스할 수 있습니다. /:name 경로는 API와 동일한 도메인(이 경우 http://localhost:2020)에서 시작된 요청을 통해서만 액세스할 수 있습니다. 🎜🎜/ 경로로 요청을 보내는 다른 출처를 시도하면 성공할 것이고 응답으로 Hello World를 받게 될 것입니다. 🎜rrreee🎜위 코드를 실행하면 서버의 응답이 콘솔에 성공적으로 출력되었습니다: 🎜rrreee🎜를 참조하세요. http://localhost:2020/name 또는 http와 같이 루트 경로가 아닌 경로에 액세스하는 경우: //localhost: 2020/img/cat.png, 이 요청은 브라우저에 의해 차단됩니다. 🎜rrreee🎜다른 웹 애플리케이션에서 코드를 실행하면 다음 오류가 표시됩니다. 🎜🎜Node.js를 사용하여 CORS를 처리하는 방법에 대한 자세한 설명🎜🎜옵션으로 CORS 구성🎜 🎜CORS를 구성하기 위해 옵션을 사용자 정의할 수도 있습니다. GETPOST와 같은 허용된 HTTP 메서드는 필요에 따라 구성할 수 있습니다. 🎜🎜CORS 옵션을 통해 단일 도메인에 대한 액세스를 허용하는 방법은 다음과 같습니다. 🎜
var corsOptions = {
    origin: 'http://localhost:8080',
    optionsSuccessStatus: 200 // For legacy browser support
}

app.use(cors(corsOptions));
로그인 후 복사
로그인 후 복사

如果你在源中配置域名-服务器将允许来自已配置域的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));
로그인 후 복사
로그인 후 복사

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

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

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

app.use(cors(corsOptions));
로그인 후 복사
로그인 후 복사

如果从 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));
로그인 후 복사
로그인 후 복사

用函数配置动态 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));
로그인 후 복사
로그인 후 복사

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

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

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

<img  alt="Node.js를 사용하여 CORS를 처리하는 방법에 대한 자세한 설명" >
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

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

<img  alt="Node.js를 사용하여 CORS를 처리하는 방법에 대한 자세한 설명" >
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

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

还可以用保存在数据库中的白名单列表或任何一种数据源来允许 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));
로그인 후 복사
로그인 후 복사

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

作者:Janith Kasun

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

위 내용은 Node.js를 사용하여 CORS를 처리하는 방법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:segmentfault.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿