XMLHttpRequest到Restivus API

时间:2015-06-15 23:55:22

标签: javascript meteor xmlhttprequest cross-domain cors

将跨域XMLHttpRequest发送到Restivus API时遇到问题。 这是我的客户端脚本代码:

var xhrurl = 'http://example.com:3000/api/test';
var xhr = createCORSRequest('POST', xhrurl);
xhr.withCredentials = true;
xhr.setRequestHeader("Content-type","application/json");
xhr.setRequestHeader("X-User-Id",object.apiUser);
xhr.setRequestHeader("X-Auth-Token",object.apiKey);
xhr.send();

这里是函数createCORSRequest

function createCORSRequest(method, url) {
  var xhr = new XMLHttpRequest();
  if ("withCredentials" in xhr) {
    xhr.open(method, url, true);
  } else if (typeof XDomainRequest != "undefined") {
    xhr = new XDomainRequest();
    xhr.open(method, url);
  } else {
    xhr = null;
  }
  return xhr;
}

将其发送到我的API时,响应是未经授权的401。 apiKey和UserId是正确的,因为我已经使用Postman对它们进行了测试,所以应该没有问题。

我的后端是Meteor,使用Restivus作为API。

我已在服务器端脚本的顶部添加了这些行,以确保所有内容都被接受。

WebApp.connectHandlers.use(function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Headers", "Content-Type, X-User-Id, X-Auth-Token");
res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
res.setHeader("Access-Control-MaxAge", "3628800");
res.setHeader("Access-Control-Allow-Credentials", true);
return next();
});

此外,我已经定义了restivus调用的路由,如下所示:

Restivus.addRoute('test/', {authRequired: true}, {
post: {
  action: function () {
    var test=Projects.find({userId:this.userId, _id: this.bodyParams.project}).count();
    if(this.bodyParams.msg==""||this.bodyParams.msg==undefined||this.bodyParams.project==""||this.bodyParams.project==undefined||test!=1){
      return 'Something went wrong'
    }
    var test = Test.insert({msg: this.bodyParams.msg, date: new Date(), userId : this.userId, fixed: false, project: this.bodyParams.project});
    if (test) {
      return {statusCode:200,headers: {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Headers': '*',
      },body: "success"};
    }
    return {
      statusCode: 400,
      body: {status: "fail", message: "Test"}
    };
  }

},
options: {
  action: function () {
      return {statusCode:200,headers: {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Method': '*',
        'Access-Control-Allow-Headers': 'Content-Type, X-User-Id, X-Auth-Token'
      }};
    }
  }
  });

我已添加了选项和发布方法以允许预检和实际发布,但我总是未经授权作为回复,尽管我在指定的restivus文档中包含登录凭据(并且它们在Postman中工作)。 那么问题出在哪里呢?

2 个答案:

答案 0 :(得分:0)

找到答案后,答案显而易见。 我只需要将restivus路由中的options方法设置为authRequired:false。 执行预检时,您无法发送包含凭据的完整标头。 现在我首先进行预检,然后发送真实的帖子。

答案 1 :(得分:0)

我已经将Restivus配置设置为

public ArrayList<Employee> getEmployeeList() {
    //check for nulls ec, ec.getUsersList and so on
    return ec.getUsersList().getUserList().stream()
        .filter(user -> user instanceof Employee)
        .collect(Collectors.toList())
}

请确保您使用的软件包版本> 0.8,以使用defaultOptionsEndpoint方法(如kahmali所评论)。无需在任何地方使用WebApp.connectHandlers。