'Access-Control-Allow-Origin' 即使采用两种方法后仍会出错

'Access-Control-Allow-Origin' error even after following 2 approaches

我正在尝试构建一个 angular 应用程序来访问 MarkLogic 数据库中的数据。我正在使用 MarkLogic rest API 来访问数据。当我尝试 运行 应用程序时,出现以下错误。

XMLHttpRequest cannot load http://192.168.192.75:9550/v1/keyvalue?element=fieldId&value=1005&format=json. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.

我在 Whosebug 上阅读了很多与此问题相关的答案,但无法解决任何问题。这是我到目前为止尝试过的方法。

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

这两种方法似乎都行不通。如果我做错了什么,谁能告诉我?或者是否还有其他方法可以使它正常工作? 提前致谢。

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

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

   <IfModule mod_headers.c>
    SetEnvIf Origin "^http(s)?://(.+\.)?(localhost|domain.com)(:[0-9]+)?$" origin_is=[=10=]
    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 ^(.*)$  [R=200,L]

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

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

我发现的另一种方法是定义我自己的转换。这仅对 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 等