【发布时间】:2018-09-17 15:45:27
【问题描述】:
此方案使用Access-Control-Allow-Credentials 和POST 方法来管理必须保持不变的服务器端PHP 会话变量。
作为参考,前端是在 http://localhost:3000 上运行的 create-react-app 项目,后端是在 example.com 上运行的 PHP。
使用$.ajax() 方法实现这一点既简单又直接。
UseAjax(incomingData) {
return new Promise(function(resolve, reject) {
$.ajax({
url: 'http://example.com/api.php',
type: 'post',
data: incomingData,
xhrFields: { withCredentials: true },
success: function(data) {
console.log(data)
}
})
.then((data,status) => {
// Get the result and transform into valid JSON
if ( typeof data === typeof 'str' ) {
try {
data = JSON.parse(data);
} catch(e) {
reject(data,status);
console.log('Exception: ', e);
console.log('API Returned non-JSON result: ', data);
}
}
return data;
}).then((dataObject) => {
console.log('dataObject:');
console.log(dataObject);
resolve(dataObject);
});
});
}
但奇怪的是,当使用fetch() API 时,给人的印象是我不允许使用CORS。当然,我启用了CORS,因为此请求适用于Ajax,并且仅在使用fetch() API 时失败。
这是我在使用fetch() API 时尝试过的内容。
UseFetch(requestData) {
return new Promise(function(resolve, reject) {
console.log('Relay() called with data: ', requestData);
fetch('http://example.com/api.php', {
method: 'POST', // or 'PUT'
body: JSON.stringify(requestData), // data can be `string` or {object}!
headers: new Headers({
'Content-Type': 'application/json'
})
}).then((result) => {
// Get the result
return result.json();
}).then((jsonResult) => {
// Do something with the result
if ( jsonResult.err )
reject(jsonResult);
console.log(jsonResult);
resolve(jsonResult);
});
});
}
它提供了这个错误。
Failed to load http://example.com/: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
在PHP 端,我使用简单的输出来确保没有其他问题会导致服务器端出现错误。
<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: http://example.com');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: Content-Type, Authorization, x-requested-with');
echo json_encode(['data'=>'result']);
?>
我关注了很多问题,但最值得注意的是this question with a very thorough explanation of the issue and possible solutions。
目前,我只是使用久经考验的$.ajax() 来完成此任务,但我想在复制此功能所需的范围内完全理解fetch() API,因为它看起来非常根据我的经验基本。
【问题讨论】:
-
您可能希望使用浏览器开发工具的“网络”窗格来查看两种情况(
$.ajax()情况和fetch()情况)的请求和响应的完整详细信息——包括完整的请求标头和请求方法以及响应标头和响应的 HTTP 状态代码 - 然后使用 stackoverflow.com/posts/49712690/edit 将这些详细信息粘贴到问题中。 -
您的 $.ajax 代码和 fetch 代码之间有一个区别:在您的 fetch 代码中,您添加了一个额外的 ContentType 标头,该标头不是由 $.ajax 代码设置的,这将强制浏览器发送预检请求。您的 php 代码似乎没有以能够正确处理预检的方式编写。但是....您的错误消息与该问题不完全匹配。错误消息指出没有访问控制标头,这可能是由于 PHP 错误导致您的标准 500 错误页面没有 CORS 标头。
标签: php ajax reactjs cors fetch