【问题标题】:implementing a javascript CORS example实现一个 javascript CORS 示例
【发布时间】:2017-03-13 15:48:59
【问题描述】:

我正在尝试执行跨域 ajax 请求 (CORS),我发现 this pretty good example 作为 MJHALL 的起始代码。

在我们的内部网络(2 个单独的域)上执行示例时,示例运行良好并返回结果。但是,当我尝试扩展它以包含我自己的一些代码时,我收到了这个错误

跨源请求被阻止:同源策略不允许读取位于http://my内部 URL.67/dirLib/listing2.php 的远程资源。 (原因:CORS 标头“Access-Control-Allow-Origin”缺失)。

这是我的代码。我的问题出现在“清单 2”中。第一个代码 sn-p 是 MJHALL 示例中的“清单 1”,我只是在其中插入了我的内部 URL。

您可以忽略清单 2 中的大部分代码。当我尝试在“$rf->p = json_decode($json);”这一行上引用我自己的代码时,问题就会出现。在清单 2 中。这里我只是尝试将传入数据存储在我的类 $rf 中的公共“$p”变量中。如果删除此行,则不会出现跨源错误。如何引用自己的代码?

<!doctype html>
 <html lang="en">
 <head>
   <script type="text/javascript">

     window.onload = doAjax();

     function doAjax() {
        var url         = "http://my internal URL.67/i/listing2.php";
        var request     = JSON.stringify({searchterm:"two"})
        var xmlhttp     = new XMLHttpRequest();

        xmlhttp.open("POST", url);
        xmlhttp.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
        xmlhttp.setRequestHeader("Access-Control-Allow-Origin", "http://my internal calling URL.23");
        xmlhttp.setRequestHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
        xmlhttp.setRequestHeader("Access-Control-Allow-Headers", "Content-Type");
        xmlhttp.setRequestHeader("Access-Control-Request-Headers", "X-Requested-With, accept, content-type");

        xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
           var jsondata = JSON.parse(xmlhttp.responseText);
           document.getElementById("id01").innerHTML = xmlhttp.responseText;
           document.getElementById("id02").innerHTML = jsondata.word;
           document.getElementById("id03").innerHTML = jsondata.RF;
       }
     };

     xmlhttp.send(request);
  }

</script>
</head>

<body>
 <div id="id01"></div>
 <div id="id02"></div>
 <div id="id03"></div>
</body>

</html>

这里是清单 2

<?php

  try
  {
    include("DBCNX.php");

    class reportFunctions
    {
       public   $errors= array(), $res_arrays= array(), $response, $p;

       function getJobInfo ()
       {
           global $dbx;

           if ( $result = $dbx->query('select something from table') )
           {
               if ($result->num_rows > 0)
               {
                   $l = mysqli_fetch_all( $result, $resulttype = MYSQLI_ASSOC );
                   $this->res_array['info'] = $l[0];
               }else{
                   $this->res_array['info']=new StdClass;
               }
           }else{
               $this->errors[] = 'Query failed!';
               $this->res_array['info']=new StdClass;
           }
           $this->res_array['errors'] = $this->errors;
           $this->response = json_encode ($this->res_array);
       }
   } // end reportFunctions Class
   $rf = new reportFunctions();

   $dictionary = array('one' => 'uno', 'two' => 'due', 'three' => 'tre');

   if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
       if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) && $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'POST') {
           header('Access-Control-Allow-Origin:  http://my internal calling URL.23');
           header('Access-Control-Allow-Headers: X-Requested-With, content-type, access-control-allow-origin, access-control-allow-methods, access-control-allow-headers');
       }
       exit;
   }

   $json = file_get_contents('php://input');
   $obj = json_decode($json);
   $rf->p = json_decode($json);

   if (array_key_exists($obj->searchterm, $dictionary)) {
       $response = json_encode(array('result' => 1, 'word' =>  $dictionary[$obj->searchterm], 'RF' => var_dump($rf->p) ));
   }
   else {
       $response = json_encode(array('result' => 0, 'word' => 'Not Found', 'RF' => var_dump($rf->p));
   }
} // end try
catch (exception $e) 
{
   $rf->res_array['errors'] =['An error occured - '.$e->getMessage()];
   $rf->response = json_encode ($rf->res_array);
}

header('Content-type: application/json');
header('Access-Control-Allow-Origin: http://my internal calling URL.23');
echo $response;

?>

这是修改后的代码,试图将类代码移入应用程序的主体

    $dictionary = array('one' => 'uno', 'two' => 'due', 'three' => 'tre');
    $errors= array(), $res_arrays= array();

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) && $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'POST') {
        header('Access-Control-Allow-Origin:  http://my internal calling URL.23');
        header('Access-Control-Allow-Headers: X-Requested-With, content-type, access-control-allow-origin, access-control-allow-methods, access-control-allow-headers');
    }
    exit;
}

$json = file_get_contents('php://input');
$obj = json_decode($json);
 // $rf->p = $obj;
if (array_key_exists($obj->searchterm, $dictionary)) {

    $sql = 'select j.jobid as job, c.name as client, j.prjctname as     project from job j left join master c on c.id = j.comid where  j.jobid='.$obj['reckey'];
    if ( $result = $db->query($sql) )
    {
        if ($result->num_rows > 0)
        {
            $l = mysqli_fetch_all( $result, $resulttype = MYSQLI_ASSOC );
            $res_array['info'] = $l[0];
        }else{
            $errors[] = 'No such job # '.$obj['reckey'];
            $res_array['info']=new StdClass;
        }
    }else{
        $errors[] = 'Query failed!';
        $res_array['info']=new StdClass;
    }
    $res_array['errors'] = $this->errors;
    $response = json_encode(array('result' => 1, 'word' =>   $dictionary[$obj->searchterm], 'RF' => var_dump($res_array) ));

}
else {
    $response = json_encode(array('result' => 0, 'word' => 'Not Found', 'RF' => var_dump($rf->p));
}
} // end try
catch (exception $e) 
{
   $res_array['errors'] =['An error occured - '.$e->getMessage()];
   $response = json_encode ($res_array);
}

header('Content-type: application/json');
header('Access-Control-Allow-Origin: http://my internal calling URL.23');
echo $response;

这里的代码是简化的发送代码

<!doctype html>
<html lang="en">

<head>
 <script type="text/javascript">

  window.onload = doAjax();

  function doAjax() {
      var url         = "http://receiving URL/listing3.php";
      var request     = JSON.stringify({searchterm:"two"})
      var xmlhttp     = new XMLHttpRequest();

      xmlhttp.open("POST", url);
      xmlhttp.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
      xmlhttp.setRequestHeader("Access-Control-Allow-Origin", "http://sending URL");
      xmlhttp.setRequestHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
      xmlhttp.setRequestHeader("Access-Control-Allow-Headers", "Content-Type");
      xmlhttp.setRequestHeader("Access-Control-Request-Headers", "X-Requested-With, accept, content-type");

      xmlhttp.onreadystatechange = function() {
      if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
          var jsondata = JSON.parse(xmlhttp.responseText);
          document.getElementById("id01").innerHTML = xmlhttp.responseText;
          document.getElementById("id02").innerHTML = jsondata.word;
      }
  };

  xmlhttp.send(request);
}

 </script>
 </head>

<body>
<div id="id01"></div>
<div id="id02"></div>
<div id="id03"></div>
</body>

</html>

这里是简化的接收代码

<?php

$dictionary = array('one' => 'uno', 'two' => 'due', 'three' => 'tre');

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) && $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'POST') {
        header('Access-Control-Allow-Origin:  http://sending URL');
        header('Access-Control-Allow-Headers: X-Requested-With, content-type, access-control-allow-origin, access-control-allow-methods, access-control-allow-headers');
    }
    exit;
}

$json = file_get_contents('php://input');
$obj = json_decode($json);
if (array_key_exists($obj->searchterm, $dictionary)) {
    $response = json_encode(array('result' => 1, 'word' => $dictionary[$obj->searchterm], 'RF' => var_dump($_POST)));
}

header('Content-type: application/json');
header('Access-Control-Allow-Origin: http://sending URL');
echo $response;

?>

这是一个修改后的接收应用程序查找表值并返回它。

<?php
$db = new mysqli("my database connection", "my user", "my password", "my database");

$dictionary = array('one' => 'uno', 'two' => 'due', 'three' => 'tre');

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) && $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'POST') {
        header('Access-Control-Allow-Origin:  http://my calling URL');
        header('Access-Control-Allow-Headers: X-Requested-With, content-type, access-control-allow-origin, access-control-allow-methods, access-control-allow-headers');
    }
    exit;
}

$json = file_get_contents('php://input');
$obj = json_decode($json);
if (array_key_exists($obj->searchterm, $dictionary)) {

        $sql = 'select myCol from myTable where myCol=myVariable';
        if ( $result = $db->query($sql) )
        {
            if ($result->num_rows > 0)
            {
                $l = mysqli_fetch_all( $result, $resulttype = MYSQLI_ASSOC );
                $RF = $l[0];
            }else{
                $RF=new StdClass;
            }
        }

    $response = json_encode(array('result' => 1, 'word' =>  $dictionary[$obj->searchterm], 'RF' => $RF));
}

header('Content-type: application/json');
header('Access-Control-Allow-Origin: http://my calling URL');
echo $response;

?>

【问题讨论】:

  • 第一条评论。我用 * 和确切的 url 地址都试过了,结果相同
  • 第二条评论。第一个 $obj 是提供的示例。只是在那里测试示例。如您在代码中看到的,第二个 $rf->p 是对我的类的引用。
  • 我现在尝试将代码移出类并移入主体,但仍然出现跨源错误。任何进一步的建议将不胜感激
  • 是的,如果我注释掉 $rf 它运行良好。我需要在我的课堂上运行代码
  • 我试一试

标签: javascript php ajax cors


【解决方案1】:

经过一天的困惑,我终于找到了工作。这是我的想法和一些观察。欢迎就如何改进提出意见。

这是一个工作示例

域 A = 发送 CORS ajax 请求

域 B = 接收 CORS ajax 请求和响应

从 DOMAIN A 上的浏览​​器启动的发送应用程序

标头中包含javascript以简化编码的显示。

<!doctype html>
<html lang="en">

<head>
    <script type="text/javascript">
        String.prototype.trim = function (){
            return this.replace(/^\s*/, "").replace(/\s*$/, "");
        }

        var g = {};

        g.formClass = function()
        {
            this.callBack, this.sendObj = {}, this.resultObj = {};

            this.getRequest = function()
            {
                if (document.getElementById("reckey").value.trim() == '')
                {
                    alert('Enter column1');
                }else{
                    this.sendObj['reckey'] = document.getElementById("reckey").value;
                    this.callBack = 'displayResult';
                    this.doAjax();
                }
            };

            this.displayResult = function(response)
            {
             this.resultObj = JSON.parse(response);
              document.getElementById("JSONresposeDisplay").innerHTML ='JSON response: '+response;
              document.getElementById("column1").innerHTML = this.resultObj.column1;
              document.getElementById("column2").innerHTML = this.resultObj.column2;
              document.getElementById("column3").innerHTML = this.resultObj.column3;
            };

            this.doAjax = function() {
                var url     = "http://999.999.99.9/receiveRequest.php";
                var request = JSON.stringify(g.c.sendObj)
                var xhr     = new XMLHttpRequest();

                xhr.open("POST", url);
                xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
                xhr.setRequestHeader("Access-Control-Allow-Origin", "http://888.888.88.8");
                xhr.setRequestHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
                xhr.setRequestHeader("Access-Control-Allow-Headers", "Content-Type");
                xhr.setRequestHeader("Access-Control-Request-Headers", "X-Requested-With, accept, content-type");

                xhr.onreadystatechange = function() {
                    if (xhr.readyState == 4 && xhr.status == 200)
                        g.c[g.c.callBack](xhr.response);            
                };

                xhr.send(request);
            };

            this.onBodyLoader = function(obj)
            {
                this.ajaxRequest = document.getElementById('ajaxRequest');
                this.ajaxRequest.addEventListener("click",function(){g.c.getRequest();}, false);
            };

        }
        g.c = new g.formClass;
    </script>
</head>

<body onLoad="g.c.onBodyLoader(this);">
    <div id="JSONresposeDisplay"></div>
    <div id="" class="">
        <table>
            <tr>
                <td>Enter Job #</td>
                <td>
                    <input type="text" id="reckey">&nbsp;
                    <input type="button" id="ajaxRequest" value="Request Info via ajax/JSON">
                </td>
            </tr><tr>
                <td>Job</td>
                <td id='column1'></td>
            </tr><tr>
                <td>Client</td>
                <td id='column2'></td>
            </tr><tr>
                <td>Project</td>
                <td id='column3'></td>
            </tr>
        </table>     
    </div>
</body>

</html>

这是 DOMAIN B 上的接收应用程序

    <?php

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) && $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'POST') {
        header('Access-Control-Allow-Origin:  http://888.888.88.8');
        header('Access-Control-Allow-Headers: X-Requested-With, content-type, access-control-allow-origin, access-control-allow-methods, access-control-allow-headers');
    }
    exit;
}

$json = file_get_contents('php://input');
$obj = json_decode($json);
    $db = new mysqli("ip address of server", "user login", "password", "dataBase");

    $sql = 'select column1, column2, column3 from table where column1='.$obj->reckey;
    if ( $result = $db->query($sql) )
    {
        if ($result->num_rows > 0)
        {
            $l = mysqli_fetch_all( $result, $resulttype = MYSQLI_ASSOC );
            $resultObject = $l[0];
        }else{
            $resultObject=new StdClass;
        }
    }

    $response = json_encode($resultObject);

header('Content-type: application/json');
header('Access-Control-Allow-Origin: http://888.888.88.8');
echo $response;

?>

我的观察:

  1. 我使用 IP 地址是因为我没有这两台服务器的域名。所以这与我在网上找到的不同。

  2. 出于某种我不明白的原因,发送请求的浏览器必须从 DOMAIN A 服务器启动。我无法使用 DOMAIN A 服务器的 URL 从另一台机器调用它。也就是说,当我从另一台机器调用它时,我得到了一个跨域错误。 我想知道原因。

  3. DOMAIN B 上的响应应该包含一些错误捕获才能完成。将对此进行研究,看看我是否可以将其合并。

欢迎提出改进代码的建议。

但至少如果其他人试图弄清楚如何做到这一点,这些示例可能会有所帮助

【讨论】:

    猜你喜欢
    • 2014-09-01
    • 2020-01-20
    • 2012-06-26
    • 1970-01-01
    • 2014-10-15
    • 2019-07-17
    • 2017-06-02
    • 1970-01-01
    相关资源
    最近更新 更多