You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用JavaScript的fetch() API发送OPTIONS * HTTP/1.1请求?

如何用fetch()发送OPTIONS * HTTP/1.1请求

根据RFC 9110(HTTP语义规范):

以星号("")作为请求目标的OPTIONS请求适用于整个服务器,而非特定资源。由于服务器的通信选项通常取决于资源,""请求仅用作“ping”或“无操作(no-op)”类型的方法;除了允许客户端测试服务器的功能外,它不执行任何操作。例如,可用于测试代理是否符合HTTP/1.1规范(或不符合)。

我在Node环境下用JavaScript编写了HTTP服务器,需要编写单元测试来验证它对以下请求的响应:

OPTIONS * HTTP/1.1

已知可以通过Curl实现该请求:

curl --request-target '*' -X OPTIONS https://example.com/

问题:如何使用fetch() API发送这个请求?


解决方案:借助undici的请求拦截器

标准fetch API(包括浏览器和Node原生实现)没有直接提供修改请求目标的接口,因为它的设计逻辑绑定了URL路径。但Node的原生fetch基于undici库,我们可以通过undici的拦截器在请求发送前修改目标为*。

示例代码:

import { fetch, Agent } from 'undici';

async function sendOptionsStarRequest() {
  // 创建带拦截器的Agent
  const customAgent = new Agent({
    interceptors: {
      request: (opts, handler) => {
        // 将请求路径替换为*,即修改请求目标
        opts.path = '*';
        return handler(opts);
      }
    }
  });

  // 发送请求,指定自定义Agent
  const response = await fetch('http://localhost:3000/', { // 替换为你的服务器地址
    method: 'OPTIONS',
    dispatcher: customAgent
  });

  // 处理响应
  console.log('响应状态码:', response.status);
  console.log('响应头:', Object.fromEntries(response.headers.entries()));
}

sendOptionsStarRequest();

原理说明

当调用fetch时,默认会把URL的路径部分作为请求目标。通过undici的请求拦截器,我们可以在请求被处理前覆盖path字段为*,从而构造出符合要求的OPTIONS * HTTP/1.1请求。

替代方案:直接使用Node内置http模块

如果单元测试无需严格依赖fetch,可以直接用Node原生http模块发送请求,代码更简洁:

import http from 'node:http';

const request = http.request({
  hostname: 'localhost',
  port: 3000,
  method: 'OPTIONS',
  path: '*' // 直接指定请求目标为*
}, (res) => {
  console.log(`状态码: ${res.statusCode}`);
  console.log(`响应头: ${JSON.stringify(res.headers)}`);
  res.resume(); // 消费响应流,避免内存泄漏
});

request.end();

内容的提问来源于stack exchange,提问作者Géry Ogam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 06:42:58