跨域(Cross-Origin)指的是在浏览器中运行的脚本试图访问不同源(Protocol、域名、端口)的资源,即在不同源之间进行数据交互。

当 JavaScript 代码尝试向不同源的服务器发起请求时,浏览器会发出“跨域请求”(Cross-Origin Request)并受到浏览器的同源策略限制。

同源策略是浏览器为了保证用户的信息安全而实施的一种安全策略,它要求浏览器限制从脚本发出的跨域 HTTP 请求,只有在同源的情况下才允许相互通信。

同源指协议、域名和端口都相同。如果两个 URL 的协议、域名或端口其中之一不同,就被认为是不同源。

跨域问题在 Web 开发中比较常见,在开发基于 AJAX 和 RESTful API 的应用时尤其需要注意。

解决跨域的方法有很多种,包括 JSONP、CORS、反向代理、WebSocket 等。

具体选择哪种方法取决于实际应用场景和需求。

koa 处理 跨域问题

设置 HTTP 响应头

在 Koa2 中解决 CORS 跨域问题的常用方法是添加一个中间件来设置 HTTP 响应头。

具体实现如下:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  // 允许跨域的域名,* 代表所有域名都可以跨域访问
  ctx.set('Access-Control-Allow-Origin', '*');
  // 允许的请求方法
  ctx.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  // 允许的请求头字段
  ctx.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');

  if (ctx.method === 'OPTIONS') {
    // 处理预检请求,直接返回 204 状态码,表示允许跨域访问
    ctx.status = 204;
  } else {
    // 继续处理正常请求
    await next();
  }
});

// 在这里注册路由处理程序
app.use(router.routes());

app.listen(3000);

在上面的代码中,我们创建了一个中间件来设置 HTTP 响应头,包括 Access-Control-Allow-Origin(允许跨域的域名)、Access-Control-Allow-Methods(允许的请求方法)和 Access-Control-Allow-Headers(允许的请求头字段)。

同时,我们也处理了预检请求 OPTIONS,如果当前请求方法是 OPTIONS,则直接返回 204 状态码表示允许跨域访问;否则,继续处理正常请求。

请注意,为了方便起见,在上面的示例中 将 Access-Control-Allow-Origin 设置为了 *,表示允许所有域名进行跨域访问。在实际应用中,我们应该根据需求设置具体的允许跨域域名

koa2-cors 库

在 Koa2 中解决跨域问题可以使用 koa2-cors 库。

下面是一个简单的示例:

首先,安装 koa2-cors

npm install koa2-cors --save

然后,在应用程序中使用这个中间件:

const Koa = require('koa');
const cors = require('koa2-cors');

const app = new Koa();

// 配置跨域选项
app.use(cors({
  origin: '*', // 允许哪些源访问,默认为 *
  maxAge: 86400, // 预检请求缓存时间(秒),默认为 5 秒
  credentials: true, // 是否携带身份验证信息,默认为 false
  allowMethods: ['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH'], // 允许哪些 HTTP 方法,默认为 GET,HEAD,PUT,POST,DELETE,PATCH
  allowHeaders: ['Content-Type', 'Authorization', 'Accept'], // 允许哪些 HTTP 头部,默认为 Content-Type,Authorization,Accept
  exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'] // 允许哪些自定义的 HTTP 头部暴露给浏览器,默认为空数组
}));

// 添加路由处理器
app.use(async (ctx, next) => {
  const name = ctx.query.name || 'World';
  ctx.body = { message: `Hello, ${name}!` };
});

app.listen(3000, () => {
  console.log('Server is running at http://localhost:3000');
});

在上面的代码中,我们导入了 koa2-cors 中间件,并将其作为第一个中间件使用。在配置选项中,我们指定了允许哪些源访问,以及是否携带身份验证信息等。这里的配置选项可以根据需要进行修改。

注意,koa2-cors 中间件必须放在其他中间件之前,否则会导致跨域请求失败。在本例中,我们添加了一个简单的路由处理器,在响应中返回一条消息,以便测试跨域请求是否起作用。

使用 koa2-cors 中间件可以方便地解决 Koa2 应用程序中的跨域问题。