Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 使用fetchapi而不是Ajax来允许凭证+;张贴请求_Php_Ajax_Reactjs_Cors_Fetch - Fatal编程技术网

Php 使用fetchapi而不是Ajax来允许凭证+;张贴请求

Php 使用fetchapi而不是Ajax来允许凭证+;张贴请求,php,ajax,reactjs,cors,fetch,Php,Ajax,Reactjs,Cors,Fetch,此场景使用Access Control Allow Credentials和POST方法来管理必须保持完整的服务器端PHP会话变量 作为参考,前端是运行在http://localhost:3000后端是运行在example.com上的PHP 使用$.ajax()方法实现这一点既简单又直接 UseAjax(incomingData) { return new Promise(function(resolve, reject) { $.ajax({ url:

此场景使用
Access Control Allow Credentials
POST
方法来管理必须保持完整的服务器端
PHP
会话变量

作为参考,前端是运行在
http://localhost:3000
后端是运行在
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时才会失败

  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);
      });
    });
  }
下面是我在使用
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);
      });
    });
  }
它提供了这个错误

加载失败http://example.com/: 请求的资源上不存在“Access Control Allow Origin”标头。起源'http://localhost:3000因此,不允许访问。如果不透明响应满足您的需要,请将请求的模式设置为“无cors”,以获取禁用cors的资源。

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()
来完成这项任务,但我想完全理解
fetch()
API,以复制此功能所需的程度,因为从我的经验来看,这似乎是非常基本的东西。

您需要后端和前端在同一服务器源上运行,请参阅本文的更多内容,因此您需要在同一服务器名下同时运行,尝试将后端移动到localhost文件夹,并使用PHP文件\u get\u contents或curl方法从api获取外部数据。

在PHP代码中,指定了
头('Access-Control-Allow-Origin:http://example.com');。这是错误的-您需要指定在原始请求头中传递的值(在您的情况下为
http://localhost:3000
):

理想情况下,您不会硬编码它-您只需提取原始请求头并将其传回


顺便说一句,我相信JQuery的$.Ajax在封面下使用fetch()(就像XmlHTTPRequest()一样)。基本上,一切都使用fetch…

请阅读问题。问题是如何使用
fetch()
而不是
$.ajax()
实现这一点。我们不愿意修改系统架构,以避免实现不佳的
fetch()
API的缺点。您可能希望使用浏览器devtools的网络窗格查看这两种情况下请求和响应的完整详细信息(
$.ajax()
情况和
fetch()
情况)-包括完整的请求头和请求方法以及响应头和响应的HTTP状态代码-然后使用将这些详细信息粘贴到问题中。在$.ajax代码和获取代码之间有一个区别:在获取代码中,您正在添加一个额外的ContentType头,该头不是由$.ajax代码设置的,这将强制浏览器发送飞行前请求。您的php代码似乎没有以正确处理飞行前的方式编写。然而。。。。您的错误消息与该问题不完全匹配。错误消息表示没有访问控制标头,这可能是由于PHP错误导致标准500错误页没有CORS标头。根据收到的错误消息,我认为这不是当前的问题,但可能是当前问题解决后的问题。当前错误消息表明没有访问控制标头。如果存在一个,但来源不匹配,则错误消息将不同。正如@sideshowbarker在其对原始帖子的评论中所建议的,您能否提供完整的请求和响应标题集?啊,我知道你不是OP。抱歉。你对jQuery的理解是错误的,它是建立在XMLHttpRequest之上的,Fetch是一个全新的API,它是在基础级别构建的。它们都用于处理使用HTTPS或HTTP标准构建在TCP/IP上的请求。但这是C++中的代码,在使用它们时,它们是完全孤立的,并且不依赖于彼此,因为XMLHtRPREQuests是第一个。如果他们要在上面构建,他们应该在上面构建,而不是重新构建XMLHttpRequest来使用FetchAPI的代码。这只是浪费时间。Martin,fetch和XMLHttpRequest是不同的,你是对的。我错了——出于某种原因,我认为XHR已经重建为使用fetch。尽管如此,否决我(否则可能是正确的)答案似乎有点苛刻,不是吗?即使它没有回答完整的问题,事实是响应头的编码不正确。唉。