【问题标题】:fetch patch request is not allowed不允许获取补丁请求
【发布时间】:2016-04-12 12:34:36
【问题描述】:

我有两个应用,一个是 react 前端,第二个是 rails-api 应用。

我一直很高兴使用isomorphic-fetch,直到我需要将 PATCH 方法发送到服务器。

我得到:

Fetch API cannot load http://localhost:3000/api/v1/tasks. Method patch is not allowed by Access-Control-Allow-Methods in preflight response.

但是来自服务器的 OPTIONS 响应在 Access-Control-Allow-Methods 列表中包含一个 PATCH 方法:

这是获取的实现方式:

const API_URL = 'http://localhost:3000/'                                            
const API_PATH = 'api/v1/'

fetch(API_URL + API_PATH + 'tasks', {
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },
  method: 'patch',                                                              
  body: JSON.stringify( { task: task } )                                        
})

POST、GET、DELETE 的设置几乎相同,并且工作正常。

知道这里发生了什么吗?

更新:

方法补丁区分大小写:

https://github.com/github/fetch/blob/master/fetch.js#L200

不确定这是故意还是错误。

更新 2

这是有意的,方法类型 PATCH 需要区分大小写。 将 fetch 方法的行更新为:

method: 'PATCH'

解决问题。

https://github.com/github/fetch/issues/254

【问题讨论】:

  • 看起来 isomorphic-fetch 中可能存在错误,因为如果我将方法名称更改为 POST,请求将起作用,但 post 不区分大小写,get delete....跨度>
  • 附带说明,在对OPTIONS 请求的响应中允许的方法的标头是Allow:。您的回复使用了不同的标头 (Access-Control-Allow-Methods:)。
  • 无论如何我认为您应该将其添加为答案,因为它是您问题的解决方案。
  • 让我了解了调查结果——将“补丁”更改为“补丁”解决了这个问题。当您需要它们时,内置枚举在哪里? :) 感谢您发布更新。
  • 与@JamesPerih 相同...用'PATCH' 替换'patch' 解决了“问题”:/

标签: javascript php ruby-on-rails fetch-api


【解决方案1】:

我在 reactJS 前端和使用 Rack::Cors 的 rails API 遇到了非常相似的问题,将 patch 添加到允许的方法列表中解决了我的问题。

config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins '*'
    resource '*', headers: :any, methods: [:get, :post, :patch, :options]
  end
end

【讨论】:

  • 这个解决方案帮助我将我的 Javascript fetch 问题修复到我的 PHP 页面。我添加了我的解决方案。
  • 这会禁用对 GET、POST、PATCH、OPTIONS 请求的 CORS 令牌检查。使您的应用程序容易受到攻击...相反,您应该在请求标头中将 cors_token 与您的请求一起传递。
【解决方案2】:

PATCH 全部大写时出现此错误。 DELETEPUT 也出现了这个错误。我检查了fetch 的标题,我看到了OPTIONS 方法。我在这里使用isomorphic-fetch lib - https://www.npmjs.com/package/isomorphic-fetch

对我来说,解决方法是添加到我的 PHP 页面:

<?php
    header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH');

如果没有这个,在 Firefox 53 中我会不断收到 javascript 错误:

尝试获取资源时出现网络错误。

我正在做的获取是这样的:

try {
    await fetch('https://my.site.com/', {
        method: 'PATCH',
        headers: { 'Content-Type':'application/x-www-form-urlencoded' },
        body: 'id=12&day=1'
    });
} catch(ex) {
    console.error('ex:', ex);
}

【讨论】:

    【解决方案3】:

    使用此代码 _method: 'PATCH'

    return (
            fetch(API_ROOT + route, {
                _method: 'PATCH',
                crossDomain: true,
                xhrFields: {
                    withCredentials: true
                },
                headers: {
                    Accept: 'application/json',
                    'Content-Type': 'application/json',
                    'Authorization': ''
                },
                data: JSON.stringify(data),
                credentials: 'include'
            })
            .then(res => res.json())
            .then(res => {
                return res
            })
            .catch(err => console.error(err))
        );
    

    另一种方式是 在标题中插入方法

    headers: {
                Accept: 'application/json',
                'Content-Type': 'application/json',
                '_method': 'PATCH',
                'Authorization': ''
            }
    

    它可以帮助你

    return (
            fetch(API_ROOT + route, {
                method: 'POST',
                crossDomain: true,
                xhrFields: {
                    withCredentials: true
                },
                headers: {
                    Accept: 'application/json',
                    'Content-Type': 'application/json',
                    '_method': 'PATCH',
                    'Authorization': ''
                },
                data: JSON.stringify(data)
            })
            .then(res => res.json())
            .then(res => {
                console.log(res);
                return res
            })
            .catch(err => console.error(err))
        );
    

    【讨论】:

    • 这也适用于 NGINX(反向代理)。它解决了我的“API 400 Bad Request during PATCH Request”。完美!
    • fetch(API_ROOT + route, {_method: 'PATCH'} 有错误应该是fetch(API_ROOT + route, {method: 'PATCH'}
    猜你喜欢
    • 2016-10-03
    • 1970-01-01
    • 2016-11-18
    • 1970-01-01
    • 2014-04-20
    • 2013-11-16
    • 1970-01-01
    • 2020-05-21
    • 1970-01-01
    相关资源
    最近更新 更多