2016-10-31 3 views
1

크로스 오리진 아약스 요청 (CORS)을하려고하는데 MHHALL의 초보자 코드로 this pretty good example이 발견되었습니다.자바 CORS 예제 구현

예제를 내부 네트워크 (2 개의 개별 도메인)에서 실행하면이 예제는 훌륭하게 작동하고 결과를 반환합니다. 내가 확장하려고 할 때 그러나, 그것은 내 자신의 코드의 일부를 포함하는, 나는이 오류를 얻을

크로스 원산지 요청 차단 : 동일한 기원 정책 http://my에서 원격 자원을 읽어 허용하지 않습니다 내부 URL.67/dirLib/listing2.php. (이유 : CORS 헤더 'Access-Control-Allow-Origin'누락).

여기 내 코드입니다. 내 문제는 "목록 2"에서 발생합니다. 첫 번째 코드 단편은 MJHALL의 예제에서 "Listing 1"로, 내부 URL을 삽입하기 만하면됩니다.

목록 2의 코드 대부분을 무시할 수 있습니다. "$ rf-> p = json_decode ($ json);"라는 줄에서 내 자신의 코드를 참조하려고하면 문제가 나타납니다. " 여기에서 나는 내 클래스 $ rf의 public "$ 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> 

코드를 단순화 응용 프로그램 여기

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

의 본체에 클래스 코드를 이동하는 수정 시도에서 코드를 여기에

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

?> 

2 리스팅됩니다 코드 전송

<!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 : 내 내부 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

나는이 일로 당혹스러워하는 날을 마침내 해결할 수있었습니다. 여기에 내가 생각해 내고 관찰 한 내용이 있습니다. 개선 방안에 대한 의견을 환영합니다.

도메인 A = CORS를 AJAX 요청 및 응답을 수신 = AJAX 요청을 CORS에게

도메인 B를 보내는 동작 예이다

DOMAIN에서 브라우저를 시작 송신 앱

자바 스크립트가 헤더에 포함되어 코딩 표시를 단순화했습니다.나는이 두 서버에 대한 도메인 이름 없었기 때문에

  1. 내가 IP 주소를 사용 :

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

    다음은 도메인 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; 
    
    ?> 
    

    내 관측이다. 그래서 제가 그물에서 찾을 수 있었던 것과는 다릅니다.

  2. 내가 이해하지 못하는 이유로, 요청을 보내는 브라우저가 DOMAIN A 서버에서 시작되어야했습니다. DOMAIN A 서버의 URL을 사용하여 다른 컴퓨터에서 불러올 수 없습니다. 즉, 다른 컴퓨터에서 호출했을 때 크로스 기점 오류가 발생했습니다. 이유를 알고 싶습니다.

  3. DOMAIN B의 응답에는 완료 할 수있는 오류 트래핑이 포함되어야합니다. 내가 그것을 통합 할 수 있는지 알아보기 위해 노력할 것입니다.

코드 개선에 대한 제안을 환영합니다.

그러나 적어도 다른 사람이 작업을 수행하는 방법을 알아 내려고 노력하는 경우, 이러한 예는