如何在Microsoft Bot Framework对话中获取网站的Referer与Origin请求头
获取Direct Line对话中前端网站的Referrer和Origin
我之前也碰到过一模一样的问题!默认情况下,Bot收到的请求都是来自Direct Line服务的转发,所以Activity.ServiceUrl返回的是Direct Line的地址,HttpContext.Current.Request.Url拿到的也是Azure服务器的内部地址,根本碰不到前端网站的真实信息。这里有两个靠谱的解决办法:
方案一:前端主动把网站信息塞进消息里(最可控)
这是我最推荐的方式,直接在你的网页代码里,用Direct Line JS SDK发送消息时,把当前页面的Origin和Referrer作为自定义数据附加到消息的channelData中:
// 前端Web Chat配置示例 const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => { // 拦截发送消息的动作 if (action.type === 'DIRECT_LINE/POST_ACTIVITY') { // 把网站的Origin和Referrer加到channelData里 action.payload.activity.channelData = { ...action.payload.activity.channelData, siteOrigin: window.location.origin, siteReferrer: document.referrer }; } return next(action); }); // 初始化Web Chat时传入这个store window.WebChat.renderWebChat({ directLine: window.WebChat.createDirectLine({ token: '你的Direct Line令牌' }), store }, document.getElementById('webchat'));
然后回到Bot的Dialog里,直接从Activity的ChannelData里读取这些值就行:
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result) { var activity = await result as Activity; string siteOrigin = null; string siteReferrer = null; if (activity.ChannelData != null) { // 解析channelData里的自定义字段 dynamic channelData = activity.ChannelData; siteOrigin = channelData?.siteOrigin; siteReferrer = channelData?.siteReferrer; } // 这里就可以用拿到的信息做逻辑处理了 await context.PostAsync($"检测到你的网站Origin:{siteOrigin},Referrer:{siteReferrer}"); context.Wait(MessageReceivedAsync); }
方案二:通过Bot的HttpContext拿请求头(需配置Azure)
如果不想改前端代码,也可以试试从Bot的HttpContext里捞请求头,但得先在Azure上做关键配置:
- 登录Azure门户,找到你的Bot对应的App Service,进入配置 > 常规设置,把ARR代理开关打开——这一步必不可少,不然Azure反向代理会把真实请求头吃掉,你拿到的还是内部地址。
- 然后在Bot代码里,通过Activity关联的HttpContext获取请求头(注意:如果是Bot Framework v3版本,用下面的代码;v4版本可以直接从
TurnContext.HttpContext获取):
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result) { var activity = await result as Activity; var httpContext = activity.GetConversationReference().GetHttpContext(); // 注意请求头的拼写是Referer(少一个r),别写错了 string origin = httpContext.Request.Headers["Origin"].FirstOrDefault(); string referrer = httpContext.Request.Headers["Referer"].FirstOrDefault(); await context.PostAsync($"从请求头拿到的Origin:{origin},Referrer:{referrer}"); context.Wait(MessageReceivedAsync); }
不过这种方式有点依赖Direct Line是否会转发这些请求头,而且环境配置容易出问题,所以还是方案一更稳妥。
内容的提问来源于stack exchange,提问作者Loai Tayem
相关产品推荐
相关产品推荐

