javascript - ASP.net、JavaScript/JQuery - 服务器发送事件 (SSE) 无法与 ASHX 处理程序一起使用

标签 javascript c# jquery asp.net ajax

我有一个 HTTP 处理程序 (ASHX),我使用 JQuery $.ajax() 函数从 UI 端调用它。此调用中需要发生以下事情:

  1. 在 UI 中创建表单数据以将文件上传到 Handler.ashx。
  2. 使用的 AJAX 请求类型是 POST。
  3. 在 Handler.ashx 中,要在 UI 上显示执行状态,我需要使用 Response.Write() 函数向 UI 发送消息,然后我正在执行 Response.Flush().
  4. 在 UI 端,我使用 XHR 的“消息”事件监听器来监听从服务器发送的数据(服务器发送事件 - SSE)。

问题是这个事件监听器不起作用,并且没有数据传递到 UI,因为事件监听器根本没有被调用。

下面是我的 JQuery 代码:

        importAjaxCall = $.ajax({
            xhr: function () {
                var xhr = new window.XMLHttpRequest();
                $('#progressBar').show();
                xhr.upload.addEventListener("progress", function (evt) {
                    if (evt.lengthComputable) {
                        var percentComplete = Math.round((evt.loaded / evt.total) * 100);
                        $('#percentageImportComplete').text('' + percentComplete + '%');
                        $('#importStatus').css('width', percentComplete + '%');
                    }
                }, false);

                xhr.addEventListener("progress", function (evt) {
                    if (evt.lengthComputable) {
                        var percentComplete = evt.loaded / evt.total;                            
                    }
                }, false);

                //This method doesn't get called for the SSE's passed
                xhr.addEventListener("message", function (event) {
                   //Some execution to be done here based upon the message being passed
                   //I am just doing an alert call for now

                   alert(event.data);
                }, false);

                return xhr;
            },
            type: 'post',
            url: "Handler.ashx",
            data: formData,
            processData: false,
            contentType: false,
            success: function (data) {
                //Some code to show success status to user
        });

这是我的 Handler.ashx 代码:

public class Handler : IHttpHandler {

public void ProcessRequest (HttpContext context) {

    HttpResponse Response = context.Response;

    //SSE Sent to show that the code execution started
    Response.Write("data: Code Execution Started");
    Response.Flush();


    /*********    Code to perform some sanity checks present here   **********/


    //SSE sent on successfull sanity checks performed
    Response.Write("data: Sanity Checks Performed");
    Response.Flush();


    /*********  Code to Copy FILE passed to File Store  ********/


    //SSE sent on successfull completion of execution of file copy
    Response.Write("data: File Successfully Copied to File Store");
    Response.Flush(); 

    Response.End();        
}

public bool IsReusable {
    get {
        return false;
    }
}
}

最佳答案

  • 将“Content-Type” header 设置为“text/event-stream”
  • 指定页面不应缓存

请参阅下面的一些实际代码:

测试.aspx

Partial Class test
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
        Try
            Response.CacheControl = "no-cache"
            Response.ContentType = "text/event-stream"
            'Response.Write(String.Format(":{0}{1}", Space(2048), vbLf))
            'Response.Write(String.Format("retry: 3000{0}", vbLf))

            Dim i As Integer = CInt(Application("lastid"))

            While True
                i += 1
                Application("lastid") = i
                Response.Write(String.Format("id: {0}{1}", i, vbLf))
                Response.Write(String.Format("data: {0:0000000} - {2:hh-mm-ss.fff} {1}{1}", i, vbLf, Now))
                Response.Flush()
                Threading.Thread.Sleep(500)
                If i Mod 1 = 0 Then
                    Exit While
                End If
            End While
        Catch ex As Exception
            Response.Write(ex.ToString)
        End Try
    End Sub
End Class

Javascript:

<script type="text/javascript">
    var content = document.getElementById("content");
    var es = new EventSource("**test.aspx**");

    es.onmessage = function (event) {
        var div = document.createElement("div");
        div.textContent = event.data;
        div.className = "console-text";
        content.insertBefore(div, content.children[0]);
        if (content.children.length > 100) {
            content.removeChild(content.childNodes[100]);
        }
    };
</script>

关于javascript - ASP.net、JavaScript/JQuery - 服务器发送事件 (SSE) 无法与 ASHX 处理程序一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29276147/

相关文章:

c# - 如何在 C# 中获取麦克风的全名?

c# - 如何在Cassandra中使用 ‘Wide Column’功能?

javascript - Jquery - 超时函数

javascript - 多个下拉按钮——一次只打开一个(JS/jQuery)

javascript - 悬停时暂停幻灯片

javascript - 基于条件检查传播 props

javascript - 为什么我不能使用函数作为 Map 的键?

c# - 拦截 WCF 客户端中的消息

javascript - 将混合心情与黑色文本混合

javascript - 未在按钮上设置内联 css