MicrosoftEdge / MicrosoftEdge/WebView2Feedback

Stream HTTP responses to WebView2

Open
#3,519 29 comments 8 reactions 3 assignees View on GitHub

@Lakshmisha-KS is already working on this.

Since Feb 12, 2025.

feature request
Dominant language
PowerShell
Stars
526
Forks
67
PR merge metrics
No merged PRs in 30d

Description

I want to stream HTTP responses to WebView2. I don't think this is possible right now, so this is a feature request.

For example, I want to intercept a request and return server-sent events which the client can process per event.

For example, I want to intercept a request and return a chunked response which the client can process incrementally.

Repro

(Or how it could work)

Host C# code
async void WebResourceRequested(CoreWebView2 sender, CoreWebView2WebResourceRequestedEventArgs args)
{
  var stream = new InMemoryRandomAccessStream();
  var writer = new DataWriter(stream);

  var response = sender.Environment.CreateWebResourceResponse(
      Content: stream, // new AsyncEnumerableRandomAccessStream(results),
      StatusCode: 200,
      ReasonPhrase: "OK",
      Headers: string.Join('\n',
          $"Content-Type: text/event-stream",
          $"Cache-Control: no-cache",
          $"Connection: keep-alive"));

  args.Response = response;

  for (int i = 0; i < 4; i++)
  {
      writer.WriteString($"event: count\n");
      writer.WriteString($"data: {{ \"count\": {i} }}\n");
      writer.WriteString("\n");
      await writer.StoreAsync();
      await writer.FlushAsync();

      await Task.Delay(200);
  }

  // or maybe deferral should be completed earlier
  // but I can continue to write to the stream?
  deferral.Complete();
}

await view.EnsureCoreWebView2Async();
view.CoreWebView2.AddWebResourceRequestedFilter("my-example-url", CoreWebView2WebResourceContext.All);
view.CoreWebView2.WebResourceRequested += WebResourceRequested;
Client JavaScript code
fetch("my-example-url")
  .then((response) => response.body.pipeThrough(new TextDecoderStream()).getReader())
  .then(async (reader) => {
    console.log("Started");
    while (true) {
      const { value, done } = await reader.read();
      if (done) {
        console.log("Completed");
        break;
      }
      console.log("Received", value);
    }
    reader.releaseLock();
  })
  .catch(console.error);

Expected

I want the response to be streamed so the client can process each event as it's sent.

Started
Received event: count
data: { "count": 0 }

Received event: count
data: { "count": 1 }

Received event: count
data: { "count": 2 }

Received event: count
data: { "count": 3 }


Completed

For example, running the JavaScript client code with the url https://sse.dev/test will behave like this.

Actual

The response is buffered and becomes available to the client all-at-once.

Started
Received event: count
data: { "count": 0 }

event: count
data: { "count": 1 }

event: count
data: { "count": 2 }

event: count
data: { "count": 3 }


Completed

System info

  • Microsoft.WindowsAppSDK 1.2.221209.1
  • Microsoft.Windows.SDK.NET 10.00.19041.28
  • Microsoft.WinUI 3.00.0.2212

AB#47606624

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.