В этом сценарии используется метод Access-Control-Allow-Credentials
вместе с методом POST
для управления переменными сеанса PHP
на стороне сервера, которые должны оставаться нетронутыми.
Для справки: внешний интерфейс — это проект create-react-app
, работающий по адресу http://localhost:3000
, а внутренний — PHP
, работающий по адресу example.com
.
Достичь этого с помощью метода $.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);
});
});
}
Как ни странно, при использовании API fetch()
создается впечатление, что я не разрешаю CORS
. Конечно, я включил CORS
, поскольку этот запрос отлично работает с Ajax
и дает сбой только при использовании API fetch()
.
Вот что я пробовал при использовании 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']);
?>
Я следил за многими вопросами, но в первую очередь этот вопрос с очень подробным объяснением проблемы и возможных решений.
На данный момент я просто использую проверенный и надежный $.ajax()
для выполнения этой задачи, но я хочу полностью понять API fetch()
в той мере, в какой это необходимо для воспроизведения этой функциональности, поскольку это кажется чем-то очень базовый из моего опыта.
Вы, вероятно, захотите использовать панель «Сеть» инструментов разработчика вашего браузера, чтобы просмотреть полную информацию о запросе и ответе для обоих случаев (случай
$.ajax()
и случайfetch()
), включая полные заголовки запроса и метод запроса, а также заголовки ответа и код состояния HTTP ответа, а затем используйте coderhelper.com/posts/49712690/edit, чтобы вставить эти данные в вопрос.Между вашим кодом $.ajax и кодом выборки есть одно различие: в коде выборки вы добавляете дополнительный заголовок ContentType, который не был установлен кодом $.ajax, что заставит браузер отправить предварительный запрос. . Ваш php-код, похоже, не написан таким образом, чтобы правильно обрабатывать предварительную проверку. Однако .... ваше сообщение об ошибке не совсем соответствует этой проблеме. В сообщении об ошибке говорится, что не было заголовка управления доступом, что может быть связано с ошибкой PHP, в результате чего на вашей стандартной странице с ошибкой 500 нет заголовков CORS.