2016-10-31 6 views
1

Я пытаюсь выполнить запрос ajax для перекрестных истоков (CORS), и я нашел this pretty good example в качестве стартового кода от MJHALL.реализация javascript Пример CORS

При выполнении примера в наших внутренних сетях (2 отдельных домена) пример отлично работает и возвращает результат. Однако, когда я пытаюсь расширить его включить некоторые из моего собственного кода, я получаю эту ошибку

Cross-Origin Request Заблокировано: The Same Origin Policy Запрещает чтение удаленного ресурса на http://my внутренний URL.67/dirLib/listing2.php. (Причина: заголовок CORS «Access-Control-Allow-Origin» отсутствует).

Вот мой код. Моя проблема возникает в «Листинге 2». Первый фрагмент кода - это «Листинг 1» в примере MJHALL, где я просто вставляю свой внутренний URL.

Вы можете игнорировать большую часть кода в листинге 2. Проблема возникает, как только я пытаюсь ссылаться на свой собственный код на этой строке «$ rf-> p = json_decode ($ json);» в листинге 2. Здесь я просто пытаюсь сохранить входящие данные в своей общедоступной переменной «$ p» в моем классе $ rf. Если я удалю эту строку, я не получаю ошибку перекрестного происхождения. Как я могу ссылаться на свой собственный код?

<!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; 

?> 
+1

Во-первых, проблема безопасности, изменение «заголовок (" Access-Control-Allow-Origin: *) ;» to "header ('Access-Control-Allow-Origin: мой внутренний URL.67');" на сервере. * означает, что любой, что делает ваш сервер более уязвимым для взлома. – Tezra

+0

И зачем вы делаете $ obj = json_decode ($ json); $ rf-> p = json_decode ($ json); вместо $ obj = json_decode ($ json); $ rf-> p = $ obj; ? (просто любопытно) – Tezra

+0

Первый комментарий. Я пробовал это с обоими * и точным адресом url, таким же результатом – Claus

ответ

1

После дня, озадачивающего это, я наконец-то получил на работу. Вот что я придумал и некоторые наблюдения. Комментарии о том, как его можно улучшить, приветствуются.

Это рабочий пример

домена А = отправка Cors АЯКС Request

домена B = прием Cors Ajax запрос и ответ

Передающий приложение запускается из браузера на домене А

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. Я не мог вызывать его с другого компьютера, используя URL-адрес сервера DOMAIN A. То есть, я получил ошибку кросс-происхождения, когда я вызывал ее с другой машины. Хотелось бы знать, почему.

  3. Ответ на DOMAIN B должен содержать некоторые ошибки, включенные в комплект поставки. Будет работать над этим, чтобы увидеть, могу ли я включить это.

Предложения по улучшению кода приветствуются.

Но, по крайней мере, если кто-то пытается выяснить, как это сделать, эти примеры могут быть полезны

Смежные вопросы