ASP.net,JavaScript / JQuery - 服务器发送事件(SSE)无法与ASHX Handler一起使用

时间:2015-03-26 10:27:12

标签: javascript c# jquery asp.net ajax

我有一个HTTP处理程序(ASHX),我使用JQuery $.ajax()函数从UI端调用。此调用需要执行以下操作:

  1. 在UI中创建表单数据以将文件上载到Handler.ashx。
  2. 使用的AJAX请求类型是POST。
  3. 在Handler.ashx中,要在UI上显示执行状态,我需要使用Response.Write()函数向我发送消息,然后我正在执行Response.Flush()
  4. 在UI端,我使用XHR的“message”事件监听器来监听从服务器发送的这些数据(Server Sent Events - SSE)。
  5. 问题是此事件侦听器无法正常工作,并且没有数据传递给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;
        }
    }
    }
    

1 个答案:

答案 0 :(得分:0)

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

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

Test.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>