我有一个运行以下标头代码的节点服务器:
app.all('/*', function (req, res, next) {
// CORS headers
res.header("Access-Control-Allow-Origin", "*"); // restrict it to the required domain
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
// Set custom headers for CORS
res.header('Access-Control-Allow-Headers', 'Content-type,Accept,X-Access-Token,X-Key');
if (req.method == 'OPTIONS') {
res.status(200).end();
} else {
next();
}
});
现在在许多计算机和浏览器上都可以正常工作(包括我自己的),但是没有坐在我办公室的人会收到以下错误消息:
好的,这很难读,所以这里有两个错误:
http://angular.mydomain.com
http://angular.mydomain.com:8080/login
。 Access-Control-Allow_origin不允许来源http://angular.mydomain.com
。谁能告诉我这里发生了什么?
接头
登录路线:
router.route('/login')
.post(function (req, res) {
var user = User.build();
var username = req.body.username || '';
var password = req.body.password || '';
if (username == '' || password == '') {
res.status(401);
res.json({
"status": 401,
"message": "Invalid credentials"
});
return;
}
var salt = bcrypt.genSaltSync(10);
var hash = bcrypt.hashSync(password, salt);
user.retrieveByNamePassword(username, function (users) {
var i = 0;
if (bcrypt.compareSync(password, users.password)) {
var log = User_Login.build()
log.findLastLogin(users.id, function (result) {
users.last_login = result;
if (users.user_type_id > 3) {
res.json(genToken(users, null));
}
else {
var div = Division.build();
selected_user = users;
var root = [selected_user.division_id];
div.retrieveByDivisionId(selected_user.division_id, function (division) {
var result = [];
var root = [division];
(function loop() {
var element = root[0];
var divisions = Division.build();
divisions.retrieveByParentId(element.id, function (divisions) {
if (divisions) {
divisions.forEach(function (division) {
root.push(division);
});
result.push(element.id);
root.splice(0, 1);
if (root.length > 0) {
loop()
}
else if (root.length == 0) {
res.json(genToken(users, result));
}
} else {
res.send(401, "No division found");
}
});
}());
})
}
}, function (error) {
var i = 0;
});
} else {
// If authentication fails, we send a 401 back
res.status(401);
res.json({
"status": 401,
"message": "Invalid credentials"
});
return;
}
}, function (error) {
res.status(401);
res.json({
"status": 401,
"message": "Invalid credentials"
});
return;
});
});
答案 0 :(得分:0)
maybe he is receiving a 404 or similar code that represents an unreachable resource from this foreign network.
答案 1 :(得分:0)
这是表达尝试处理OPTIONS
请求的情况。我建议在最后一段修改,但如果你想更全面地了解为什么会发生这种情况,请仔细阅读。
为什么会有OPTIONS
个请求?这就是所谓的“预检”(read about it here)。基本上,如果请求是跨域的并且看起来“危险”(“安全”请求是GET
/ HEAD
/ POST
,没有自定义标头和application/x-www-form-urlencoded
/ multipart/form-data
/ text/plain
作为Content-Type
),浏览器首先发送OPTIONS
请求,以确保允许跨源请求。如果设置了正确的标题,它将发送实际的请求。
您正在尝试在app.all
处理程序中设置正确的标头,但它们不在响应中。
首先,我们来看看如何表达处理请求。它首先运行附加到app
的所有中间件(按照它附加的顺序)。 “中间件”是与app.use
相关联的任何内容。然后,它按照它们所附的顺序经过每条路线。路由是与app.all
,app.get
等相关联的任何内容。如果这些步骤中的任何一个未能调用next
(通常是因为他们发送了响应),则链将停止。
由于您的标头是在app.all
中设置的,因此它们是路由阶段的一部分。由于您将router
与app.use
相关联,因此它是中间件阶段的一部分。
但是,看到OPTIONS
请求的快速路由器的URL与其中一条路由匹配会产生一些特殊情况。如果它在未完成请求的情况下到达该路由器的末尾,它会自动发送带有Allow
标头集的响应。这就是为什么请求永远不会进入设置标头的app.all
路由。
建议的修复:在中间件(OPTIONS
)中设置标头(并在方法为app.use
时发送响应),而不是路由。您还必须确保在处理/login
的路由器之前连接此中间件。
因此,请使用app.all('/*',
代替app.use('/',
。确保在app.use('/', router)
之前发生这种情况。