IE 11 + SignalR 不工作
IE 11 + SignalR not working
St运行ge 行为在 IE 11 中使用 signalR 时发生。场景:
我们有一些调度程序类型的功能,其中调度程序执行一些操作,而其他用户可以实时查看更新(查询)。发送的参数通过正常并导致 IE 客户端更新,而无需打开开发者控制台。
但是有一种方法不起作用(performUpdate
- 获取查询结果 - 这是服务器 > 客户端调用,而不是客户端 > 服务器 > 客户端) - 永远不会被调用。它仅在开发者控制台打开时被调用。
这是我尝试过的:
Why JavaScript only works after opening developer tools in IE once?
SignalR : Under IE9, messages can't be received by client until I hit F12 !!!!
一些代码片段
调度方
在下拉列表更改时,我们获取当前选择的值并通过网络发送更新。 (这很好用)。
$('#Selector').on('change', function(){
var variable = $('#SomeField').val();
...
liveBatchHub.server.updateParameters(variable, ....);
});
服务器端
当调度程序搜索时,我们有一些服务器端代码会发出搜索已完成的通知 运行,并告诉客户端提取结果。
public void Update(string userId, Guid bId)
{
var context = GlobalHost.ConnectionManager.GetHubContext<LiveBatchViewHub>();
context.Clients.User(userId).performUpdate(bId);
}
客户端(实时更新的查看者)
除非打开开发者工具,否则永远不会调用此方法
liveBatchHub.client.performUpdate = function (id) {
//perform update here
update(id);
};
编辑
多一点可能有用的信息(我不确定为什么会有所不同)但这似乎只有在我进行服务器 > 客户端调用时才会发生。当调度程序更改搜索参数时,更新是客户端>服务器>客户端或调度程序客户端>服务器>查看器客户端,这似乎有效。单击搜索后,搜索管道中的服务会调用 performUpdate
服务器端(服务器 > 查看器-客户端)。不确定这是否重要?
编辑 2 和最终解决方案
眼睛充血,我意识到我遗漏了这个问题的一个关键部分:我们在这个页面上也使用了angular。我想我已经盯着它看了太久而把它漏掉了 - 抱歉。我给了 JDupont 答案,因为他走在正确的轨道上:缓存。但不是 jQuery 的 ajax 缓存,angular 的 $http.
为了让其他人不必花费数日/数夜的时间将头撞在桌子上,最终的解决方案是使用 angulars $http 禁用 ajax 调用的缓存。
取自here:
myModule.config(['$httpProvider', function($httpProvider) {
//initialize get if not there
if (!$httpProvider.defaults.headers.get) {
$httpProvider.defaults.headers.get = {};
}
// Answer edited to include suggestions from comments
// because previous version of code introduced browser-related errors
//disable IE ajax request caching
$httpProvider.defaults.headers.get['If-Modified-Since'] = 'Mon, 26 Jul 1997 05:00:00 GMT';
// extra
$httpProvider.defaults.headers.get['Cache-Control'] = 'no-cache';
$httpProvider.defaults.headers.get['Pragma'] = 'no-cache';
}]);
我过去在 IE 中遇到过类似的行为。我可能知道您的问题的解决方案。
IE 默认缓存一些 ajax 请求。您可能想尝试全局关闭此功能。看看这个:How to prevent IE from caching Ajax with jQuery
基本上你会像这样全局关闭它:
$.ajaxSetup({ cache: false });
或针对特定的 ajax 请求,例如:
$.ajax({
cache: false,
//other options...
});
我的 GET 请求缓存也有类似的问题。除非打开开发工具,否则我的更新功能只会触发一次。当它打开时,不会发生缓存。
如果您的代码在其他浏览器上正常工作,那么问题可能出在 SignalR 使用的传输方法上。它们可以是 WebSocket, Server Sent Events, Forever Frame 和 Long Polling 基于浏览器支持。
Forever Frame 仅适用于 Internet Explorer。你可以看到 Introduction to SignalR to know which transport method will be used in various cases (Note that you can't use any of them on each browser, for example, IE doesn't support Server Sent Events).
您只需查看请求的 QueryString
即可了解集线器内部使用的传输方法,这对日志记录很有用:
Context.QueryString["transport"];
我认为问题可能来自 IE 使用 Forever Frame,因为有时它会导致 SignalR 在 Ajax 调用时崩溃。您可以尝试删除 SignalR 中的 Forever Frame 支持,并在客户端使用以下代码强制浏览器使用其余支持的方法:
$.connection.hub.start({ transport: ['webSockets', 'serverSentEvents', 'longPolling'] });
我展示了有关 SignalR 的一些实际情况,并为您提供了一些 logging/trace 工具来解决您的问题。如需更多帮助,请提供更多详细信息:)
更新:
由于您的问题似乎很奇怪,而且我对您的代码没有足够的了解,因此我根据我的经验向您提出一些说明希望对您有用:
- 设置浏览器Link在IDE适合
- 在处理过程中检查“网络”选项卡 request/response 数据
- 确保您没有在 server/client 端使用保留名称
(也许通过重命名方法和变量)
此外,我认为您需要在 Dispatcher 端 中使用 liveBatchHub.server.update(variable, ....);
而不是 liveBatchHub.server.updateParameters(variable, ....);
来进行服务器调用,因为您应该在之后使用服务器方法名称server
.
St运行ge 行为在 IE 11 中使用 signalR 时发生。场景:
我们有一些调度程序类型的功能,其中调度程序执行一些操作,而其他用户可以实时查看更新(查询)。发送的参数通过正常并导致 IE 客户端更新,而无需打开开发者控制台。
但是有一种方法不起作用(performUpdate
- 获取查询结果 - 这是服务器 > 客户端调用,而不是客户端 > 服务器 > 客户端) - 永远不会被调用。它仅在开发者控制台打开时被调用。
这是我尝试过的:
Why JavaScript only works after opening developer tools in IE once?
SignalR : Under IE9, messages can't be received by client until I hit F12 !!!!
一些代码片段
调度方
在下拉列表更改时,我们获取当前选择的值并通过网络发送更新。 (这很好用)。
$('#Selector').on('change', function(){
var variable = $('#SomeField').val();
...
liveBatchHub.server.updateParameters(variable, ....);
});
服务器端
当调度程序搜索时,我们有一些服务器端代码会发出搜索已完成的通知 运行,并告诉客户端提取结果。
public void Update(string userId, Guid bId)
{
var context = GlobalHost.ConnectionManager.GetHubContext<LiveBatchViewHub>();
context.Clients.User(userId).performUpdate(bId);
}
客户端(实时更新的查看者)
除非打开开发者工具,否则永远不会调用此方法
liveBatchHub.client.performUpdate = function (id) {
//perform update here
update(id);
};
编辑
多一点可能有用的信息(我不确定为什么会有所不同)但这似乎只有在我进行服务器 > 客户端调用时才会发生。当调度程序更改搜索参数时,更新是客户端>服务器>客户端或调度程序客户端>服务器>查看器客户端,这似乎有效。单击搜索后,搜索管道中的服务会调用 performUpdate
服务器端(服务器 > 查看器-客户端)。不确定这是否重要?
编辑 2 和最终解决方案
眼睛充血,我意识到我遗漏了这个问题的一个关键部分:我们在这个页面上也使用了angular。我想我已经盯着它看了太久而把它漏掉了 - 抱歉。我给了 JDupont 答案,因为他走在正确的轨道上:缓存。但不是 jQuery 的 ajax 缓存,angular 的 $http.
为了让其他人不必花费数日/数夜的时间将头撞在桌子上,最终的解决方案是使用 angulars $http 禁用 ajax 调用的缓存。
取自here:
myModule.config(['$httpProvider', function($httpProvider) {
//initialize get if not there
if (!$httpProvider.defaults.headers.get) {
$httpProvider.defaults.headers.get = {};
}
// Answer edited to include suggestions from comments
// because previous version of code introduced browser-related errors
//disable IE ajax request caching
$httpProvider.defaults.headers.get['If-Modified-Since'] = 'Mon, 26 Jul 1997 05:00:00 GMT';
// extra
$httpProvider.defaults.headers.get['Cache-Control'] = 'no-cache';
$httpProvider.defaults.headers.get['Pragma'] = 'no-cache';
}]);
我过去在 IE 中遇到过类似的行为。我可能知道您的问题的解决方案。
IE 默认缓存一些 ajax 请求。您可能想尝试全局关闭此功能。看看这个:How to prevent IE from caching Ajax with jQuery
基本上你会像这样全局关闭它:
$.ajaxSetup({ cache: false });
或针对特定的 ajax 请求,例如:
$.ajax({
cache: false,
//other options...
});
我的 GET 请求缓存也有类似的问题。除非打开开发工具,否则我的更新功能只会触发一次。当它打开时,不会发生缓存。
如果您的代码在其他浏览器上正常工作,那么问题可能出在 SignalR 使用的传输方法上。它们可以是 WebSocket, Server Sent Events, Forever Frame 和 Long Polling 基于浏览器支持。
Forever Frame 仅适用于 Internet Explorer。你可以看到 Introduction to SignalR to know which transport method will be used in various cases (Note that you can't use any of them on each browser, for example, IE doesn't support Server Sent Events).
您只需查看请求的 QueryString
即可了解集线器内部使用的传输方法,这对日志记录很有用:
Context.QueryString["transport"];
我认为问题可能来自 IE 使用 Forever Frame,因为有时它会导致 SignalR 在 Ajax 调用时崩溃。您可以尝试删除 SignalR 中的 Forever Frame 支持,并在客户端使用以下代码强制浏览器使用其余支持的方法:
$.connection.hub.start({ transport: ['webSockets', 'serverSentEvents', 'longPolling'] });
我展示了有关 SignalR 的一些实际情况,并为您提供了一些 logging/trace 工具来解决您的问题。如需更多帮助,请提供更多详细信息:)
更新: 由于您的问题似乎很奇怪,而且我对您的代码没有足够的了解,因此我根据我的经验向您提出一些说明希望对您有用:
- 设置浏览器Link在IDE适合
- 在处理过程中检查“网络”选项卡 request/response 数据
- 确保您没有在 server/client 端使用保留名称 (也许通过重命名方法和变量)
此外,我认为您需要在 Dispatcher 端 中使用 liveBatchHub.server.update(variable, ....);
而不是 liveBatchHub.server.updateParameters(variable, ....);
来进行服务器调用,因为您应该在之后使用服务器方法名称server
.