Bot Framework Webchat 无法从 Node.js restify 服务器(在 Azure 上)获取令牌:CORS 策略:不存在 'Access-Control-Allow-Origin' header
Bot Framework Webchat unable to get token from Node.js restify server (on Azure): CORS policy: No 'Access-Control-Allow-Origin' header is present
要启动 Bot Framework 网络聊天客户端,我需要 'get' 来自 Azure 中的 restify 服务器 运行 的令牌。服务器从 https://webchat.botframework.com/api/tokens 获取令牌(使用我的秘密)。最后一部分工作正常。第一部分没有。我没有设法让网络聊天客户端接受来自 restify 服务器的响应。离线(本地主机)工作正常。当服务器 运行 在线时(Azure 中的节点)我得到:
Access to fetch at 'https://mybot.azurewebsites.net/api/token' from origin 'https://mydomainname.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
在 chrome 的开发工具中,我可以看到在本地主机上使用 restify 服务器 运行,我得到一个 access-control-allow-origin 和一个 access-control-expose-header。当 运行 在节点上(在 Azure 中)我只得到 access-control-expose-header.
我已经尝试了什么(没有好的结果):
- 为 restify 服务器实现 cors 中间件
- 使用 Express 而不是 restify
- 手动将 headers 添加到响应中:res.send(token, { 'Access-Control-Allow-Origin': '*' })
- 在 Cors 中间件的(可信)来源列表中指定域名
- [the solution] add the domain name running the calling javascript in the list with approved origins in the azure app service running the restify service.
我当前的代码(使用 Cors 中间件)
重新设置服务器
const fetch = require('node-fetch');
const restify = require('restify');
const path = require('path');
const corsMiddleware = require('restify-cors-middleware');
const cors = corsMiddleware({
origins: ['*']
});
// Create HTTP server and Cors
let server = restify.createServer();
server.use(cors.actual);
server.listen(process.env.port || process.env.PORT || 3978, function() {
console.log(`\n${ server.name } listening to ${ server.url }.`);
console.log(`\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator.`);
});
// Listen for bot requests.
server.post('/api/messages', (req, res) => {
adapter.processActivity(req, res, async (context) => {
await bot.run(context);
});
});
// Listen for token requests.
server.get('/api/token',
async function(req, res) {
const result = await fetch('https://webchat.botframework.com/api/tokens', {
method: 'GET',
headers: {
Authorization: `Bearer ${ process.env.directLineSecret }`
}
});
const token = await result.json();
console.log(token);
res.send(token);
});
网络聊天客户端
在此代码片段中,客户端正在与本地主机上的服务器 运行 通信。这行得通。一旦我们与托管在 Azure 上的服务器对话,它就不再工作了(似乎是因为 cors)
(async function () {
const res = await fetch('http://localhost:3978/api/token', { method: 'GET' });
const webChatToken = await res.json();
window.WebChat.renderWebChat({
directLine: window.WebChat.createDirectLine({ token: webChatToken })
}, document.getElementById('webchat'));
document.querySelector('#webchat > *').focus();
})().catch(err => console.error(err));
有人知道如何解决这个问题吗?
让我搜索了一天并尝试了很多选项。
解决方案在
您必须在 appservice 运行 您的 restify 服务的 CORS 菜单中的已批准来源列表中添加调用域。
不确定这是否有意义,但它有所帮助。
要启动 Bot Framework 网络聊天客户端,我需要 'get' 来自 Azure 中的 restify 服务器 运行 的令牌。服务器从 https://webchat.botframework.com/api/tokens 获取令牌(使用我的秘密)。最后一部分工作正常。第一部分没有。我没有设法让网络聊天客户端接受来自 restify 服务器的响应。离线(本地主机)工作正常。当服务器 运行 在线时(Azure 中的节点)我得到:
Access to fetch at 'https://mybot.azurewebsites.net/api/token' from origin 'https://mydomainname.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
在 chrome 的开发工具中,我可以看到在本地主机上使用 restify 服务器 运行,我得到一个 access-control-allow-origin 和一个 access-control-expose-header。当 运行 在节点上(在 Azure 中)我只得到 access-control-expose-header.
我已经尝试了什么(没有好的结果):
- 为 restify 服务器实现 cors 中间件
- 使用 Express 而不是 restify
- 手动将 headers 添加到响应中:res.send(token, { 'Access-Control-Allow-Origin': '*' })
- 在 Cors 中间件的(可信)来源列表中指定域名
- [the solution] add the domain name running the calling javascript in the list with approved origins in the azure app service running the restify service.
我当前的代码(使用 Cors 中间件)
重新设置服务器
const fetch = require('node-fetch');
const restify = require('restify');
const path = require('path');
const corsMiddleware = require('restify-cors-middleware');
const cors = corsMiddleware({
origins: ['*']
});
// Create HTTP server and Cors
let server = restify.createServer();
server.use(cors.actual);
server.listen(process.env.port || process.env.PORT || 3978, function() {
console.log(`\n${ server.name } listening to ${ server.url }.`);
console.log(`\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator.`);
});
// Listen for bot requests.
server.post('/api/messages', (req, res) => {
adapter.processActivity(req, res, async (context) => {
await bot.run(context);
});
});
// Listen for token requests.
server.get('/api/token',
async function(req, res) {
const result = await fetch('https://webchat.botframework.com/api/tokens', {
method: 'GET',
headers: {
Authorization: `Bearer ${ process.env.directLineSecret }`
}
});
const token = await result.json();
console.log(token);
res.send(token);
});
网络聊天客户端
在此代码片段中,客户端正在与本地主机上的服务器 运行 通信。这行得通。一旦我们与托管在 Azure 上的服务器对话,它就不再工作了(似乎是因为 cors)
(async function () {
const res = await fetch('http://localhost:3978/api/token', { method: 'GET' });
const webChatToken = await res.json();
window.WebChat.renderWebChat({
directLine: window.WebChat.createDirectLine({ token: webChatToken })
}, document.getElementById('webchat'));
document.querySelector('#webchat > *').focus();
})().catch(err => console.error(err));
有人知道如何解决这个问题吗?
让我搜索了一天并尝试了很多选项。
解决方案在
您必须在 appservice 运行 您的 restify 服务的 CORS 菜单中的已批准来源列表中添加调用域。 不确定这是否有意义,但它有所帮助。