5

我正在尝试构建一个角度应用程序来访问 MarkLogic 数据库中的数据。我正在使用 MarkLogic REST API 来访问数据。当我尝试运行该应用程序时,我收到以下错误。

XMLHttpRequest 无法加载 http://192.168.192.75:9550/v1/keyvalue?element=fieldId&value=1005&format=json。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此不允许访问源“ http://localhost:8080 ”。

我在stackoverflow上阅读了很多与此问题相关的答案,但没有任何工作。这是我到目前为止所尝试的。

1) Setting the response header using xdmp in qconsole
xdmp:add-response-header("Access-Control-Allow-Origin", "*");
xdmp:add-response-header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
xdmp:add-response-header("Access-Control-Allow-Headers", "x-requested-with, X-Auth-Token, Content-Type");
2) Tried to add headers by using REST [Extention][1]. Here is the example.sjs file which I wrote.
a) function get(context, params) {
  var results = [];
  context.outputTypes = [];
  for (var pname in params) {
    if (params.hasOwnProperty(pname)) {
      results.push({name: pname, value: params[pname]});
      context.outputTypes.push('application/json');
    }
  }
  context.outputStatus = [201, 'Created My New Resource'];
    context.outputHeaders = 
    {'Access-Control-Allow-Origin' : '*', 'Access-Control-Allow-Methods' : 'GET, OPTIONS, DELETE', 'Access-Control-Allow-Headers' : 'x-requested-with, X-Auth-Token, Content-Type'};
  return xdmp.arrayValues(results);
};
exports.GET = get;
b) curl --anyauth --user admin:admin -X PUT -i -H "Content-type: application/vnd.marklogic-javascript" --data-binary @./example.sjs http://192.168.192.75:9550/LATEST/config/resources/example

无论哪种方式,它似乎都不起作用。谁能告诉我我做错了什么?或者如果有任何其他方法可以让这个工作?提前致谢。

4

2 回答 2

1

这可能是由于Access-Control-Allow-Origin在进行身份验证时不允许使用 *。或者可能是由于在请求非标准时发送的飞行前请求。飞行前是在 GET/POST/etc 之前发送的 OPTIONS 请求。验证是否可以进行实际调用。我们解决这个问题的方法是使用 Apache HTTP 作为代理在 MarkLogic REST 端点前面。我们在虚拟主机配置中有以下内容。

ProxyPass 是映射到 ML REST 端点的代理的位置。其他东西将Access-Control-Allow-Origin标头设置为请求主机的名称。这是必需的,因为身份验证时不允许使用“*”。和设置用于响应飞行前的 OPTIONS 请求,并仅返回 HTTP 200 状态RewriteCondRewriteRule

   <IfModule mod_headers.c>
    SetEnvIf Origin "^http(s)?://(.+\.)?(localhost|domain.com)(:[0-9]+)?$" origin_is=$0
    Header always set Access-Control-Allow-Origin %{origin_is}e env=origin_is
    Header always set Access-Control-Allow-Methods "POST, GET, PUT, DELETE, OPTIONS"
    Header always set Access-Control-Max-Age "1000"
    Header always set Access-Control-Allow-Headers "X-Requested-With, content-type, Access-Control-Allow-Origin, Authorization, X-User-Id"
  </IfModule>

  RewriteEngine on
  RewriteCond %{REQUEST_METHOD} OPTIONS
  RewriteRule ^(.*)$ $1 [R=200,L]

  # People DB REST Endpoint
  ProxyPass /people_dev http://10.239.12.223:8050

您可以对 NginX 或任何其他 HTTP 代理执行相同的操作。

于 2016-06-16T13:53:27.663 回答
1

我发现的另一种方法是定义我自己的变换。这仅对 GET 请求方法有帮助,对其他人没有帮助。这是我创建的。

function customCors(context, params, content)
{
    xdmp.addResponseHeader('Access-Control-Allow-Origin' , '*');
    xdmp.addResponseHeader('Access-Control-Allow-Methods' , 'GET, PUT, POST, HEAD, OPTIONS, DELETE' );
    xdmp.addResponseHeader('Access-Control-Allow-Headers' , 'X-Requested-With, X-Auth-Token, Content-Type, Accept');
    return content;
};

exports.transform = customCors;

要使用它,我们必须使用一个名为 transform 的属性。像这样。

http://192.168.192.75:9550/v1/keyvalue?element=fieldId&value=1005& transform=customCors &format=json

更新:联系 MarkLogic,他们说这不能以 2 层方法完成。我们必须有一个像 java 这样的中间层(3 层)来添加 Origins/Methods 等。

于 2016-06-17T15:33:32.107 回答