我正在尝试做一个交叉起源的ajax请求(CORS),我发现this pretty good example是MJHALL的初始代码。
在我们的内部网络(2个独立的域)上执行示例时,该示例效果很好并返回结果。但是,当我尝试将其扩展为包含我自己的一些代码时,我收到此错误
阻止跨源请求:同源策略禁止在http://my内部URL.67 / dirLib / listing2.php读取远程资源。 (原因:缺少CORS标题'Access-Control-Allow-Origin'。
这是我的代码。我的问题出现在“清单2”中。第一个代码片段是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;
?>
答案 0 :(得分:2)
经过一天的困惑,我终于得到了一些工作。以下是我提出的建议和一些观察。欢迎评论如何改进它。
这是一个有效的例子
域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">
<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;
?>
我的观察:
我使用的是IP地址,因为这两台服务器没有域名。这与我在网上找到的不同。
由于某些我不明白的原因,发送请求的浏览器必须从DOMAIN A服务器启动。我无法使用DOMAIN A服务器的URL从其他计算机上调用它。也就是说当我从另一台机器调用它时,我遇到了一个跨源错误。 我想知道原因。
DOMAIN B上的响应应包含一些错误捕获以完成。将继续努力,看看我是否可以将其纳入其中。
欢迎有关改进代码的建议。
但至少如果其他人试图弄清楚如何做到这一点,这些例子可能会有所帮助