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。
我在向 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。