我有两个应用程序,一个是反应前端,第二个是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方法:
这是fetch的实现方式:
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'
解决了这个问题。
答案 0 :(得分:6)
我使用Rack :: Cors与reactJS前端和rails API有一个非常类似的问题,并且在允许的方法列表中添加patch
为我解决了这个问题。
config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*', headers: :any, methods: [:get, :post, :patch, :options]
end
end
答案 1 :(得分:1)
我在PATCH
全部上限时遇到此错误。我也在DELETE
和PUT
收到此错误。我检查了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错误:
尝试获取资源时出现NetworkError。
我正在做的抓取是这样的:
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);
}
答案 2 :(得分:0)
使用此代码 _方法:“ 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))
);