即使遵循2种方法,也会出现“访问控制 - 允许 - 来源”错误

时间:2016-06-15 16:55:10

标签: cors marklogic marklogic-8 marklogic-7

我正在尝试构建一个角度应用程序来访问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

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

2 个答案:

答案 0 :(得分:1)

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

ProxyPass是映射ML REST端点的代理的地方。其他内容将Access-Control-Allow-Origin标头设置为请求主机的名称。这是必需的,因为' *'在进行身份验证时不允许。 RewriteCondRewriteRule设置用于响应飞行前OPTIONS请求,只返回HTTP 200状态。

   <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代理执行相同操作。

答案 1 :(得分: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&变换= customCors &安培;格式= JSON

更新:与MarkLogic接触,他们说这不能用2层方法完成。我们必须有一个像java这样的中间层(3层)来添加起源/方法等。