首页 > 解决方案 > 使用带有 PHP 代理的 jQuery AJAX 请求检索数据时出现问题

问题描述

我正在为一家公司面试,他们给了我一个带回家的任务,我有无限的时间来完成。其中一项规范是我使用 PHP API 代理来绕过他们的 API 的 CORS。除了 JQuery,我不允许为此使用任何 PHP 或 JS 库。我对 PHP 非常陌生,并且习惯于使用 React 获取数据,所以我感觉有点不适应。我发现在我看来它应该是一个解决方案:

https://github.com/joseftw/php-rest-proxy

...但我无法让它工作。每当我加载页面并检查控制台时,它只会保留<empty string>GET 和 POST 请求(在 Firefox 上)。console.log('test')我知道呼叫正在触发,因为如果我添加它,它们确实会执行。那么数据在哪里呢?

这是我的 PHP 代理文件的代码:

    <?php

  $url = $_REQUEST["url"];

  if(!$url) {
    echo "You need to pass in a target URL.";
    return;
  }

  $response = "";
  switch (getMethod()) {
    case 'POST':
      $response = makePostRequest(getPostData(), $url);
      break;
    case 'GET':
      $response = makeGetRequest($url);
      break;
    default:
      echo "This proxy only supports POST AND GET REQUESTS.";
      return;
  }

  echo $response;

  function getMethod() {
    return $_SERVER["REQUEST_METHOD"]; 
  }

  function getPostData() {
    return http_build_query($_POST);
  }

  function makePostRequest($data, $url) {
    $httpHeader = array(
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data));
    
    return makePutOrPostCurl('POST', $data, true, $httpHeader, $url);
  }

  function makeGetRequest($url) {
    $ch = initCurl($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $response = curl_exec($ch);
    curl_close($ch);

    return $response;
  }

  function makePutOrPostCurl($type, $data, $returnTransfer, $httpHeader, $url) {

    $ch = initCurl($url);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $type);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, $returnTransfer);
    
    $response = curl_exec($ch);
    curl_close($ch);
    return $response;
  }

  function initCurl($url) {
    $httpHeader = array(
    'Content-Type: application/x-www-form-urlencoded');

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $httpHeader);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36');

    return $ch;
  }


?>

这是我的 script.js 文件中的 AJAX 请求:

$(document).ready(function () {
    $.ajax({
        url: 'proxy.php?url=https://reqres.in/api/users',
        type: 'POST',
        data: { name: 'Zlatan Ibrahimovic' },
        success: function (data) {
            console.log(data);
        },
    });

    $.get('proxy.php?url=https://reqres.in/api/users', function (data) {
        console.log(data);
    });
});

我提供的端点来自示例 API,而不是公司的 API。尽管如此,我还是无法让代理/AJAX 组合与任何东西一起使用。这是第二天,我正在旋转我的轮子。谁能指出我正确的方向?我完全不使用 PHP 代理设置,还是其他原因?

标签: javascriptphpajaxproxy

解决方案


我在脚本正文中使用 JS 脚本。一旦我得到响应,我使用 document.getElementById('result') 将它发送回 dom --- 见里面的 html 正文;当我尝试使用 /users 时,即使该链接有结果,我也没有得到任何有趣的结果。我认为您要访问的链接是 /user。我为 url 添加了 isset 验证。否则,当您不在导航器 url 中添加 ?url 时,它会中断。

<?php
$url = null;

if (isset($_REQUEST["url"])) {
    $url = $_REQUEST["url"];
}

if(!$url) {
    echo "You need to pass in a target URL.";
    return;
}

$response = "";

switch (getMethod()) {
    case 'POST':
        $response = makePostRequest(getPostData(), $url);
        break;
    case 'GET':
        $response = makeGetRequest($url);
        break;
    default:
        echo "This proxy only supports POST AND GET REQUESTS.";
        return;
}

echo $response;

function getMethod() {
    return $_SERVER["REQUEST_METHOD"];
}

function getPostData() {
    return http_build_query($_POST);
}

function makePostRequest($data, $url) {
    $httpHeader = array(
        'Content-Type: application/json',
        'Content-Length: ' . strlen($data));

    return makePutOrPostCurl('POST', $data, true, $httpHeader, $url);
}

function makeGetRequest($url) {
    $ch = initCurl($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    print_r($response);

    curl_close($ch);

    return $response;
}

function makePutOrPostCurl($type, $data, $returnTransfer, $httpHeader, $url) {

    $ch = initCurl($url);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $type);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, $returnTransfer);

    $response = curl_exec($ch);
    curl_close($ch);
    return $response;
}

function initCurl($url) {
    $httpHeader = array(
        'Content-Type: application/x-www-form-urlencoded');

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $httpHeader);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36');

    return $ch;
}

?>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<div id="result"></div>
<script type="module">
    addEventListener('DOMContentLoaded', () => {
        console.log('ok');
        const xhtml = new XMLHttpRequest();

        xhtml.onreadystatechange = (res) => {
            if ((res.target.status === 201 || res.target.status === 200) && res.target.readyState === 4) {
                console.log('----------------res object--------------------' + "<::::>");
                console.log(res, "res");

                console.log('----------------status--------------------' + "<::::>");
                console.log(res.target.status);

                console.log('------------------readyState------------------' + "<::::>");
                console.log(res.target.readyState);

                console.log('------------------response------------------' + "<::::>");
                console.log(res.target.response);

                console.log('------------------responseText------------------' + "<::::>");
                console.log(res.target.responseText);
                document.getElementById('result').innerText = res.target.responseText;
            }
        }
        xhtml.open('POST', 'https://reqres.in/api/user');

        xhtml.send(JSON.stringify({
            url: 'proxy.php?url=https://reqres.in/api/user',
            type: 'POST',
            data: {name: 'Zlatan Ibrahimovic'},
        }));
    });
</script>
</body>
</html>

如果您想使用提供的 url 替换此行 ...xhtml.open('POST', 'https://reqres.in/api/user');

       const url = JSON.parse(`<?php echo $url?>`);
        xhtml.open('POST', url);

        xhtml.send(JSON.stringify({
            url: 'proxy.php?url=' + url,
            type: 'POST',
            data: {name: 'Zlatan Ibrahimovic'},
        }));

推荐阅读