我正在尝试将Amazon CloudSearch集成到SilverStripe中。我想做的是,当页面发布时,我希望 CURL 请求将有关页面的数据作为 JSON 字符串发送到搜索云。
我使用 http://docs.aws.amazon.com/cloudsearch/latest/developerguide/uploading-data.html#uploading-data-api 作为参考。
每次我尝试上传它时,它都会返回我一个 403。我也允许搜索域的访问策略中的 IP 地址。
我将其用作代码参考:https://github.com/markwilson/AwsCloudSearchPhp
我认为问题是AWS未正确进行身份验证。如何正确验证这一点?
如果您收到以下错误
403 禁止,行政规章禁止的请求。
如果您确定您有适当的规则生效,我会检查您正在使用的 api URL。请确保使用的是正确的终结点。如果您正在进行批量上传,则 api 端点应如下所示
您的搜索文档端点/2013-01-01/文档/批处理
通知 2013-01-01,这是 url 的必需部分。这是您将使用的 api 版本。即使可能有意义,您也无法执行以下操作
您的搜索文档端点/文档/批处理
要搜索,您需要点击以下 API
您的搜索端点/2013-01-01/搜索?您的搜索参数
经过多次搜索和反复试验,我能够将一个小代码块放在一起,从来自任何地方的小代码片段到能够使用 CURL 和 PHP 将"文件"上传到 aws cloudsearch。
最重要的一件事是确保您的数据已正确准备以 JSON 格式发送。
注意:对于云搜索,您上传的文件不是发布 JSON 数据流。这就是为什么我们中的许多人在上传数据时遇到问题的原因。
因此,就我而言,我希望能够在clousearch上上传我的搜索引擎的数据,这似乎很简单,但是缺少示例代码来执行此操作并不是大多数人告诉您去通常有示例的文档,但要使用aws CLI。php SDK 只是一个学习限制加号,而不是让它变得简单,你做 20 个步骤来完成 1 个任务,不仅你需要拥有所有这些其他库,这些库只是本机 PHP 函数的包装器,有时而不是让它变得简单它变得复杂。
所以回到我是如何做到的,首先我从我的数据库中提取数据作为一个数组,并序列化它以将其保存到一个文件中。
$row = $database_data;
foreach ($rows as $key => $row) {
$data['type'] = 'add';
$data['id'] = $row->id;
$data['fields']['title'] = $row->title;
$data['fields']['content'] = $row->content;
$data2[] = $data;
}
// now save your data to a file and make sure
// to serialize() it
$fp = fopen($path_to_file, $mode)
flock($fp, LOCK_EX);
fwrite($fp, serialize($data2));
flock($fp, LOCK_UN);
fclose($fp);
现在您已经保存了数据,我们可以使用它
$aws_doc_endpoint = '{Your AWS CloudSearch Document Endpoint URL}';
// Lets read the data
$data = file_get_contents($path_to_file);
// Now lets unserialize() it and encoded in JSON format
$data = json_encode(unserialize($data));
// finally lets use CURL
$ch = curl_init($aws_doc_endpoint);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Length: ' . strlen($data)));
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$response = curl_exec($ch);
curl_close($ch);
$response = json_decode($response);
if ($response->status == 'success')
{
return TRUE;
}
return FALSE;
就像我说的,它什么都没有。我遇到的大多数答案,使用 Guzzle 它真的很容易,嗯,是的,但对于像这样的简单任务,你不需要它。
除此之外,如果您仍然遇到错误,请务必检查以下内容。
格式正确的 JSON 数据。确保有权访问终结点。
好吧,我希望有人发现这段代码有帮助。
要诊断这是否是访问策略问题,您是否尝试过允许对上传进行所有访问的策略? 如下所示的内容可以打开所有内容:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "cloudsearch:*"
}
]
}
我注意到,如果您只是在浏览器中转到文档上传端点(我的看起来像"doc-YOURDOMAIN-RANDOMID.REGION.cloudsearch.amazonaws.com"),即使使用开放访问,您也会收到 403"管理规则禁止的请求"错误,因此正如@dminer所说,您需要确保发布到正确的完整 url。
您是否考虑过使用 PHP SDK?就像 http://docs.aws.amazon.com/aws-sdk-php/guide/latest/service-cloudsearchdomain.html 一样。 它应该负责提出正确的请求,在这种情况下,您可以排除传输错误。
我从来没有用过。 我使用云搜索终端上传文件。 和 PHP 卷曲来搜索文件。
尝试将"cloudsearch:document"添加到 CloudSearch 的访问策略中的"操作"下
我在403 Forbidden, Request forbidden by administrative rules
上遇到了同样的问题。这完全是由于使用文档端点添加API版本,如下所示。
插入云搜索时,添加此部分非常重要:
由于您尝试将数据插入云搜索,因此需要使用 AWS 提供给您的云搜索的文档端点。
它后面需要跟着 API 版本,如下所示:
https://doc-xxxxx.zzzz.cloudsearch.amazonaws.com/2013-01-01/documents/batch
同时要注意添加内容类型,否则最终可能会HTTP 415 Unsupported Media Type
错误。
addRequestHeader("Content-Type", "application/xml");