我有一个SPA(反应),它使用PHP调用来连接到MongoDB。
效果很好。
但是,由于“规则”,我需要从其他服务器(不支持MongoDB或MongoDB php客户端的服务器)提供javascript文件。我们称这个服务器为SERVER_A。
让我们调用托管MongoDB PHP客户端和MongoDB的服务器SERVER_B。 (“ B”代表“后端” ... :))
我认为,解决方案是在SERVER_A上构建一个php'middleman',将数据简单地传递到SERVER_B。研究表明,file_get_contents
是实现这一目标的工具。
因此,我将原始的已知有效的PHP文件放入SERVER_B上,并将其重命名为“ mongoPatch_backend.php”。
<?php
$user = "xxxx";
$pwd = 'xxx';
$filter = [];
if (isset($_REQUEST['needleKey'])) {
$needleKey = $_REQUEST['needleKey'];
$needle = $_REQUEST['needle'];
$filter = [$needleKey => $needle];
}
$newData = $_REQUEST['newData'];
$filter = ['x' => ['$gt' => 1]];
$options = [
'projection' => ['_id' => 0],
'sort' => ['x' => -1],
];
$bson = MongoDB\BSON\fromJSON($newData);
$value = MongoDB\BSON\toPHP($bson);
$manager = new MongoDB\Driver\Manager("mongodb://${user}:${pwd}@SERVER_B:27017");
$bulk = new MongoDB\Driver\BulkWrite;
$bulk->update(
[$needleKey => $needle],
['$set' => $value],
['multi' => false, 'upsert' => true]
);
$results = $manager->executeBulkWrite('sedwe.users', $bulk);
var_dump($results);
?>
然后在SERVER_A上创建一个新文件dbPatch.php,如下所示:
<?php
$API = "https://SERVER_B/php/mongoPatch_backend.php?";
if (isset($_REQUEST['needleKey'])) {
$needleKey = $_REQUEST['needleKey'];
$needle = $_REQUEST['needle'];
$filter = [$needleKey => $needle];
}
$newData = $_REQUEST['newData'];
$postData = "needleKey=".urlencode($needleKey);
$postData .= "&needle=".urlencode($needle);
$postData .= "&newData=".urlencode($newData);
// echo $API.$postData;
$data = file_get_contents($API.$postData);
echo $data;
?>
但是当我调用它时,我从$ data中得到的回声什么也没有。
知道为什么吗?请记住,直接对mongoPatch_backend.php进行完全相同的调用也可以正常工作(但这是CORS调用,因此不是有效选项)。
这就是我尝试过的事情:
首先,为了确保我的AJAX调用仍在工作,我向控制台吐出了响应。我什么都没有。
因此,我将中间人的最后一行(dbPatch.php)更改为echo "Hello World"
而不是echo $data
,并按预期在控制台上收到了“ Hello World”。
接下来,我然后将中间人(dbPatch.php)的最后一行改回echo $data
,并尝试将'后端'简化为简单的<?php echo "Hello Back World"; ?>
,在控制台上什么也没得到。
接下来,我在浏览器中转到https://SERVER_B/php/mongoPatch_backend.php ...并按预期在浏览器中向您问好“ Hello Back World”。
...这使我相信,从服务器到服务器的信息传输是有问题的。逻辑通话,是吗?
不幸的是,当我仅使用'fetch'命令尝试相同的操作时,它的工作原理就很好:
这是我在SERVER_A上的“中间人”(dbFetch.php)脚本:
<?php
$API = "https://SERVER_B/php/mongoFetch_backend.php?";
$collection = $_REQUEST['collection'];
$postData = "collection=".urlencode($collection);
$needleID = $_REQUEST['needleID'];
$postData .= "&needleID=".urlencode($needleID);
$data = file_get_contents($API.$postData);
echo $data;
?>
这是后端SERVER_B上的文件:
<?php
$user = "xxxx";
$pwd = 'xxxx';
$filter = [];
if (isset($_REQUEST['needleID'])) {
$needleID = $_REQUEST['needleID'];
$filter = ['id'=> $needleID];
}
if (isset($_REQUEST['collection'])) {
$collection = $_REQUEST['collection'];
}
//Manager Class
$connection = new MongoDB\Driver\Manager("mongodb://${user}:${pwd}@SERVER_B:27017");
// Query Class
$query = new MongoDB\Driver\Query($filter);
$rows = $connection->executeQuery("db_name.$collection", $query);
// Convert rows to Array and send result back to client
$rowsArr = $rows->toArray();
echo json_encode($rowsArr);
?>
Huzzah,这个可行! ...并且也证明了服务器之间的通信似乎没有问题。
所以回到零。
然后我使用一个非常简单的newData
值-较短,但总体布局相同-字符串化json。有用!数据最终存储在数据库中。
所以我被迫认为newData
中的数据有问题(这只是几百行这样的字符串化JSON:encodeURIComponent(JSON.stringify(newData))
。但是,这需要重复:如果我跳过中间人,就可以工作。
...这让我很茫然。我不太了解PHP ...您能帮忙吗?
编辑以回答评论:
当我直接在SERVER_B上调用mongoPatch_backend.php时,它可以工作(如上所述)。我让它回显$newData
,它吐出了变量的字符串化JSON版本(未进行URL编码)。
当我调用dbPatch.php时,它没有任何从mongoPatch_backend传回的信息。
正如我在OP中所述,如果我修改mongoPatch_backend.php以使其不执行echo echo“ hellow world”,那么当通过上述dbPatch.php文件调用它时,我仍然无法将其登录到控制台。
编辑:我还尝试将两个PHP文件放在同一服务器上,并且得到相同的结果。 (即dbPatch.php和mongoPatch.php文件都在同一服务器上的同一目录中)
EDIT2:我从中间人那里做了一个var_dump,我得到了标准外观的人类可读的字符串化文本。
我在后端文件中执行相同的var_dump($_REQUEST['newData']);
,但什么也没回来。