Javascript 设置了节点头,但有些用户遇到访问控制错误
我有一个运行以下标头代码的节点服务器:Javascript 设置了节点头,但有些用户遇到访问控制错误,javascript,node.js,Javascript,Node.js,我有一个运行以下标头代码的节点服务器: 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,OPTION
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:8080/login
。来源<代码>http://angular.mydomain.com是Access-Control-Allow\u origin不允许的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;
});
});
可能他正在从该外部网络接收表示无法访问的资源的404或类似代码。可能他正在从该外部网络接收表示无法访问的资源的404或类似代码。这是express试图处理
选项
请求的情况。我建议在最后一段中进行修复,但如果您想更彻底地理解为什么会发生这种情况,请通读一遍
为什么会有选项
请求?这就是所谓的“飞行前”(preflight)。本质上,如果请求是跨源的并且看起来“危险”(“安全”请求是GET
/HEAD
/POST
,没有自定义头,并且是应用程序/x-www-form-urlencoded
/多部分/表单数据
/文本/普通
作为内容类型
)中的一个,浏览器首先发送一个OPTIONS
请求,以确保允许跨原点请求。如果设置了正确的头,它将发送实际的请求
您正在尝试在应用程序中设置正确的标题。所有处理程序,但它们不在响应中
首先,让我们看一下Express是如何处理请求的。它首先运行连接到
app
的所有中间件(按照连接顺序)。“中间件”是与应用程序相关的任何东西。请使用。然后,它按照连接的顺序通过每条路线。路由是与app.all
、app.get
等附加的任何内容。如果这些步骤中的任何一个未能调用next
(通常是因为它们发送了响应),链将停止
由于您的标题是在应用程序中设置的。所有,因此它们是路由阶段的一部分。由于您使用应用程序连接路由器
,因此它是中间件阶段的一部分
然而,如果一个快速路由器看到一个OPTIONS
请求,并且URL与它的一条路由匹配,那么它会做一些特殊的事情。如果它到达路由器的末端而没有完成请求,它会自动发送一个带有Allow
头集的响应。这就是为什么请求从未发送到您的应用程序。所有设置标题的路由
建议的修复方法:在中间件(app.use
)而不是路由中设置标题(如果方法是OPTIONS
),并发送响应)。您还必须确保在处理/login
的路由器之前连接此中间件
因此,请使用app.use('/*',
),而不要使用app.all('/',
。请确保在app.use('/',路由器)之前执行此操作
这是express试图处理选项
请求的案例。我建议在最后一段中进行修复,但如果您想更彻底地理解发生这种情况的原因,请通读一遍
为什么会有一个OPTIONS
请求?这就是所谓的“飞行前”(preflight)请求。本质上,如果请求是跨源的,看起来“危险”(“安全的”)请求是GET
/HEAD
/POST
,没有自定义的头,并且应用程序/x-www-form-urlencoded
/多部分/表单数据
/文本/普通
中的一个作为内容类型
),浏览器首先发送一个OPTIONS
请求,以确保允许跨源请求。如果设置了正确的标题,则浏览器将发送实际请求
您正在尝试在应用程序中设置正确的标题。所有处理程序,但它们不在响应中
首先,让我们看看Express是如何处理一个请求的,它首先运行所有连接到App的中间件(按照它的顺序)。是与应用程序连接的任何内容。使用。然后,它按照连接顺序通过每个路由。路由是与应用程序连接的任何内容。所有,应用程序。获取,等等。如果这些步骤中的任何一个未能调用下一步(通常是因为它们发送了响应),链将停止
由于您的头是在应用程序中设置的。所有
,它们都是路由阶段的一部分。由于您将路由器
与应用程序连接。使用
,它是中间件阶段的一部分
但是,如果一个快速路由器看到一个选项
请求,并且URL与它的一个路由匹配,它会做一些特殊的事情。如果它到达该路由器的末端而没有完成请求,它会自动发送一个带有允许
头集的响应。这就是为什么该请求永远不会发送到你的应用程序。所有rou设置标题的te
建议的修复方法:在中间件(应用程序。使用
)中设置标题(如果方法是选项,则发送响应),而不是路由。您还必须确保在处理/login
的路由器之前连接此中间件
因此,请使用app.all('/*',
),而不要使用app.use('/',
。请确保在app.use('/',router)
之前进行此操作。此人(“不坐在我办公室的人”)是否可以确认他们正在获取(或未获取)哪些CORS头