Этот сценарий использует Access-Control-Allow-Credentials
вместе с методом POST
для управления переменными сеанса PHP
стороне сервера, которые должны оставаться неповрежденными.
Для справки, front-end представляет собой проект create-react-app
работающее на http://localhost:3000
а на внутреннем сервере - PHP
работающий на example.com
.
$.ajax()
этого с помощью $.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()
.
Вот посмотрите, что я пытался использовать API fetch()
.
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 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()
-and-true $.ajax()
для выполнения этой задачи, но я хочу полностью понять API-интерфейс fetch()
в той мере, в какой это необходимо для репликации этой функции, поскольку она кажется чем-то очень простым по моему опыту.
В вашем PHP-коде вы указали header('Access-Control-Allow-Origin: http://example.com');
, Это неверно - вам нужно указать значение, переданное в заголовке запроса Origin (который в вашем случае будет http://localhost:3000
):
header('Access-Control-Allow-Origin: http://localhost:3000');
В идеале вы не будете жестко кодировать его - вы просто извлечете заголовок запроса Origin и передадите его обратно.
Кстати, я считаю, что JQuery $.Ajax использует fetch() под обложками (точно так же, как XmlHTTPRequest()). В принципе, все использует выборку...
Вам нужно, чтобы внутренний и внешний интерфейсы выполнялись на одном и том же сервере, см. Больше в этой ссылке, поэтому вам нужно запустить обе стороны с одним и тем же именем сервера, попытаться переместить фоновый код в папку localhost и использовать PHP file_get_contents или curl-метод для получения внешних данных из api.
fetch()
вместо $.ajax()
. Мы не хотим переделывать системную архитектуру, чтобы избежать недостатков плохо реализованного API fetch()
.
$.ajax()
случайfetch()
), включая полные заголовки запроса и метод запроса. и заголовки ответа и код состояния HTTP ответа - и затем используйте stackoverflow.com/posts/49712690/edit, чтобы вставить эти детали в вопрос.