要启动 Bot Framework 网络聊天客户端,我需要从运行在 Azure 中的 restify 服务器“获取”一个令牌。服务器从https://webchat.botframework.com/api/tokens获取令牌(使用我的秘密)。最后一部分工作正常。第一部分没有。我没有设法让网络聊天客户端接受来自 restify 服务器的响应。离线(本地主机)工作正常。当服务器在线运行(Azure 中的节点)时,我得到:
CORS 策略阻止从源“ https://mydomainname.com ”获取“ https://mybot.azurewebsites.net/api/token ”的访问权限:不存在“Access-Control-Allow-Origin”标头在请求的资源上。
在 chrome 的开发工具中,我可以看到在本地主机上运行 restify 服务器,我得到了一个 access-control-allow-origin 和一个 access-control-expose-header。在 Node(在 Azure 中)上运行时,我只得到 access-control-expose-header。
我已经尝试了什么(没有好的结果):
- 为 restify 服务器实现 cors 中间件
- 使用 Express 代替 restify
- 手动将标头添加到响应中: res.send(token, { 'Access-Control-Allow-Origin': '*' })
- 在 Cors middelware 的(受信任的)来源列表中指定域名
- 【解决方案】在运行restify服务的azure app服务中,将运行调用javascript的域名添加到已获批准的来源列表中。
我当前的代码(使用 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));
有人对如何解决这个问题有任何想法吗?