XMLHttpRequest 到 Restivus API

XMLHttpRequest to Restivus API

我在向 Restivus 发送跨域 XMLHttpRequest 时遇到问题 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测试过,应该没有问题。

我的后端是使用 Restivus 的 Meteor 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'
      }};
    }
  }
  });

我已经添加了选项和 post 方法以允许预检和实际 post 然后我总是得到未经授权的响应,尽管我像在指定的 restivus 文档中包含登录凭据(他们确实在 Postman 工作)。 那么问题出在哪里呢?

知道后答案就很明显了。 我只需要将 restivus 路由中的选项方法设置为 authRequired: false。 进行预检时,您无法发送带有凭据的完整 header。 现在我先做预检,然后发送真正的 post.

我已经将我的 Restivus 配置设置成这样,

let Api = new Restivus({
    useDefaultAuth: false,
    prettyJson: true,
    version: 'v1',
    enableCors: false, // or set true in production
    defaultOptionsEndpoint: {
        action: function() {
            this.response.writeHead(201, {
                'Access-Control-Allow-Origin': '*',
                'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Z-Key, X-Auth-Token, X-User-Id',
                'Content-Type': 'application/json',
                'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS'
            });
            this.done();
            return { status: true }
        }
    },
});

确保您使用的包版本 > 0.8,以便使用 defaultOptionsEndpoint 方法,正如 kahmali 评论的那样。无需在任何地方使用 WebApp.connectHandlers。