HTTP 405 方法不允许:路由、方法与 CORS

HTTP 405 方法不允许详解

Scrapeless Web Unlocker 为必须区分 HTTP 方法错误与有效响应的数据工作流获取公共页面内容。

HTTP 405 方法不允许表示服务器识别该请求方法,但不允许其用于目标资源。URL 与方法形成一对:接受页面读取的路由,可能会拒绝表单提交或更新。请从实际收到该响应的请求入手,而不是从你期望客户端发送的方法开始。

摘要

  • 405 关注的是某个资源允许使用的方法。 它并不表示服务器上的每个路由都拒绝该方法。
  • 在 405 响应中必须包含 Allow 头。 它描述目标资源当前支持的方法。
  • 浏览器预检可能在目标操作被发送之前就失败。 检查是 OPTIONS 还是应用请求收到了错误。
  • 将写操作改成 GET 会改变操作的含义。 修正文档中的 API 合约和路由,而不是盲目更换方法。

资源边界上的 HTTP 405 含义

HTTP 405 标识的是已被识别的方法与目标资源所支持方法之间的不匹配。 HTTP 语义规范 要求在响应中提供 Allow 头,列出资源当前支持的方法。该头是诊断证据,尽管实际实现可能不完整或配置不当。

资源边界很重要。一个服务可以在一条路由上接受 POST,而在另一条路由上对 POST 返回 405。浏览器地址栏通常执行的是页面导航,而应用客户端则可能发送带有消息体的不同方法。到达相同的主机名并不意味着这些请求履行相同的合约。

将 405 与服务器层面无法识别或未实现的方法区分开来,也要将其与授权失败和内容缺失区分开来。该状态将调查范围缩小到方法与资源之间的关系,但自定义中间件或网关仍可能在应用处理程序运行前就生成响应。

检查真正失败的那个请求

实际的网络请求是 405 诊断的起点。记录最终 URL、请求方法、响应状态码、Allow 头、内容类型以及相关的重定向链。在共享这些记录前,删去授权信息和敏感查询参数。

将观测到的方法与文档中的操作进行比较。表单可能提交到了页面路由而不是 API 路由。客户端可能在 API 版本变更后仍使用旧路径。结尾斜杠重定向可能让请求经过与你预期不同的路由。当你只查看发起该操作的源代码时,这些细节可能是不可见的。

不要从可读的错误页面推断路由已成功匹配。反向代理、静态主机、框架或应用都可以生成解释 405 的 HTML。通过日志和配置识别是哪一层生成了响应。响应中的品牌信息是线索,但并不能证明是否有应用处理程序看到该请求。

阅读 Allow 而不要把它当作授权

Allow 描述的是支持的方法;它并不授予执行这些方法的权限。一个端点可以声明支持某个方法,同时仍然要求认证、适当的凭据或有效的请求体。修复 405 之后,可能会暴露出单独的校验错误,因为请求终于到达了预期的处理程序。

如果缺少 Allow,请记录该响应缺失必需的头,而不是凭空编造方法列表。使用 API 规范和可由所有者控制的路由配置来确定预期的合约。不符合规范的响应应该触发服务器端调查,而不是促使你在生产资源上尝试所有可能的方法。

方法名本身携带语义。读取、更新和删除是不同的操作,即便路由接受多种方法。为避免 405 而将有状态更改操作改为 GET,会造成不安全的缓存与导航行为。应选择文档中描述的操作,并修复错误拒绝它的组件。

常见路由与部署不匹配

在部署或集成变更过程中,路由配置可能会偏离客户端合约。表单处理程序可能在静态部署中缺失,网关可能只暴露部分方法,或带版本的 API 路由可能与公共页面路径不同。将失败的请求与实际部署的路由表进行匹配。

情形需要对比的证据可能的责任方
表单 POST 达到了仅提供页面的路由表单的 action、method 与服务器路由前端与应用团队
API 方法未在网关配置中出现网关路由与后端合约API 平台团队
OPTIONS 在应用方法前就失败浏览器网络请求序列与 CORS 策略网关或应用团队
只有部署环境返回 405构建产物、路由注册与主机配置部署团队
重定向改变了目标地址每个重定向响应及最终请求路由或应用团队

精确比较各环境。开发服务器可能实现了一个生产主机从未部署的 API 处理程序。因此,本地测试成功只验证了本地路由。在修改客户端之前,请检查已部署的工件和公共路由规则。

CORS 预检请求与 405 相关但并不相同

浏览器可以在预期的跨源操作之前发送一个 CORS 预检请求。 获取标准的 CORS 协议 定义了此浏览器行为。如果预检请求收到 405,应用程序请求可能永远不会被发送,即使浏览器控制台将整体失败描述为 CORS 问题。

检查网络面板中出错行的请求方法。如果是 OPTIONS,请检查预检处理程序以及允许的来源、方法和请求头策略。如果是实际的 POST 或其他应用方法,请单独排查该操作的路由。不要假定在任意错误页面上添加响应头就能同时解决这两种情况。

Allow 头部和 Access-Control-Allow-Methods 的用途不同。前者用来告知资源支持哪些方法;后者参与浏览器的跨域权限决策。服务器可以支持某个方法,却拒绝某个特定的跨域浏览器请求。反过来,宽松的 CORS 头部并不会凭空创建一个原本不存在的应用路由。

重定向可能会隐藏原始方法问题

重定向可以更改目标地址,并且根据状态码和客户端行为,影响请求的后续执行方式。应当检查每一次跳转,而不是将最终 URL 视为客户端最初直接访问的地址。重定向后保留或选择的请求方法在目标资源具有不同方法契约时尤为重要。

一个示例性的表单流程可能会提交到一个旧的路由,该路由会重定向到某个登陆页面。这个登陆页面本身也许是一个有效页面,但却是无效的表单端点。如果预期的处理程序位于其他位置,那么更改该登陆页面的 method 策略只会解决错误的问题。应当修复将请求发送到那里的表单 action 或迁移规则。

在授权环境中使用无害操作来测试重定向。不要仅为了获得更干净的诊断跟踪而重放付款、删除或其他写操作。确定原始操作是否可能产生了副作用,并在发起任何新的状态更改之前,使用应用程序对该操作的记录。

缓存可能会保留先前的 405

根据 HTTP 规则,缓存可以保留某些响应,因此已更正的路由可能不会立即在每个观测到的响应中体现出来。 HTTP 缓存语义 解释新鲜度和验证行为。当观察到的 405 与已部署的处理程序不一致时,检查与缓存相关的响应元数据和当前生效的缓存策略。

在再次更改路由之前,先确定响应是来自缓存还是当前应用程序。源站上的配置修复与缓存失效决策是两个独立的操作。保留原始响应和当前预期响应的证据,以便在事件记录中显示是哪个层负责导致问题。

在没有理由的情况下避免进行广泛的缓存删除。通过针对性调查,可以将受影响的路由、方法和缓存键与当前已知的响应进行比较。修正应与过期结果的范围相匹配,而不是干扰无关的站点内容。

在公共页面集合中处理 405

收集器应将 405 保留为方法错误,并将返回的错误主体保留在其目标数据集之外。记录错误是来自收集服务的 API 调用还是来自目标资源。这是不同的契约,修复其中一个不一定会影响另一个。

Web Unlocker 通过其有文档记录的服务接口检索内容。 Web Unlocker 合同 对于受支持的请求,而不是假设转发到目标的任意方法都是可用的。即使应用程序从未直接公开这两者,服务方法与目标方法之间的概念性区分依然是有用的。

请提供需要从英文翻译成中文(zh)的文本。 Next.js 内容提取讨论 提供了有关选择正确内容界面的相关背景。仅仅因为涉及同一页面,已渲染页面、应用程序数据响应和 API 操作并不能互换使用。请查看当前 无抓取定价 在建立正确的集合路径之后,这样工作量估算才能反映有用的请求。

在维修完成后确认合同

完成的修复应在预期的已部署资源上演示预期的方法。确认响应状态、所需数据以及预期的副作用(如果有)。同时确认不受支持的方法仍然受控,并且该更改没有意外扩大对无关路由的访问。

当事故暴露出不匹配时,更新客户端合约或路由文档。在问题发生的方法-资源边界处加入一个最小的回归检查。这比仅仅断言主页仍然可访问的测试更有用,因为主页可能从未调用过发生故障的方法。

结论

在没有相反证据之前,HTTP 405 是一个路由和方法契约问题。捕获实际使用的方法,检查 Allow,并将预检请求与应用程序操作区分开来。修复已部署的契约并验证其预期行为,而不是削弱认证或将写操作改成读操作。

选择正确的内容检索合约

使用 Web Unlocker 来检索受支持的公共页面,并将方法错误保留为明确的采集结果。

今天注册即可获得 5 美元免费额度 — 无需信用卡.

领取你的 $5 额度 →

常见问题

问:405 是否意味着该 URL 不存在?

405 表示目标资源不允许使用该方法。它与资源缺失的响应不同。请同时验证确切的路由和方法,因为一个可正常浏览的页面路由可能并不接受所请求的 API 操作。

问:如果 Allow 头缺失怎么办?

缺少 Allow 头会让 405 响应在 HTTP 语义下不完整。记录这一遗漏,并检查 API 合约或路由配置。不要仅凭状态码去猜测支持哪些方法。

问:405 一定是 CORS 错误吗?

405 并不总是 CORS 错误。CORS 预检可能会收到 405,但同源请求或非浏览器客户端也可能收到它。检查是 OPTIONS 失败还是目标应用方法失败。

问:代理可以修复方法不匹配吗?

更换代理并不能修复错误的路由-方法约定。代理本身也可能是拒绝该方法的组件,所以当有相关迹象时要检查其配置。网络路由和 API 语义仍然是两个独立的关注点。

问:为什么 GET 可以用但 POST 不行?

GET 可以工作而 POST 失败,是因为该资源支持读取,但没有被允许的提交处理程序。确认 POST 是否属于另一个已文档化的端点,以及该处理程序是否已部署。

参考资料