Skip to content

Commit fe03e64

Browse files
committed
Create WebResourceResponseReceived.md
1 parent 6d95286 commit fe03e64

1 file changed

Lines changed: 219 additions & 0 deletions

File tree

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
# Background
2+
The WebView2 team has been asked for an API to get the response for a web
3+
resource as it was received and to provide request headers not available when
4+
`WebResourceRequested` event fires (such as Authentication headers). The
5+
`WebResourceResponseReceived` event provides such HTTP response representation
6+
and exposes the request as sent over the wire.
7+
8+
In this document we describe the new API. We'd appreciate your feedback.
9+
10+
# Description
11+
The `WebResourceResponseReceived` event fires when the WebView receives the
12+
response for a request for a web resource. It provides access to both the
13+
response as it was received and the request as it was sent over the wire,
14+
including modifications made by the network stack (such as adding of
15+
Authorization headers). The app can use this event to view the actual request
16+
and response for a web resource, but modifications made to these objects are
17+
ignored.
18+
19+
The host app registers for this event by providing a
20+
`WebResourceResponseReceivedEventHandler` (or delegate) to WebView's
21+
`add_WebResourceResponseReceived`/`WebResourceResponseReceived`. When invoking
22+
the handler, the WebView will pass a `WebResourceResponseReceivedEventArgs`,
23+
which lets the app view the request and response. The additional
24+
`PopulateResponseContent` API is exposed from the event arguments so the app
25+
can get the response's body (if it has one).
26+
27+
# Examples
28+
The following code snippets demonstrates how the `WebResourceResponseReceived`
29+
event can be used:
30+
31+
## COM
32+
```cpp
33+
EventRegistrationToken m_webResourceResponseReceivedToken = {};
34+
35+
m_webview->add_WebResourceResponseReceived(
36+
Callback<ICoreWebView2WebResourceResponseReceivedEventHandler>(
37+
[this](ICoreWebView2* webview, ICoreWebView2WebResourceResponseReceivedEventArgs* args)
38+
-> HRESULT {
39+
// The request object as sent by the wire
40+
wil::com_ptr<ICoreWebView2WebResourceRequest> webResourceRequest;
41+
CHECK_FAILURE(args->get_Request(&webResourceRequest));
42+
// The response object as received
43+
wil::com_ptr<ICoreWebView2WebResourceResponse> webResourceResponse;
44+
CHECK_FAILURE(args->get_Response(&webResourceResponse));
45+
46+
// Get body content for the response. Redirect responses will
47+
// return an error HRESULT as their body (if any) is ignored.
48+
HRESULT populateCallResult = args->PopulateResponseContent(
49+
Callback<
50+
ICoreWebView2WebResourceResponseReceivedEventArgsPopulateResponseContentCompletedHandler>(
51+
[this, webResourceRequest, webResourceResponse](HRESULT result) {
52+
// The response might not have a body.
53+
bool populatedBody = SUCCEEDED(result);
54+
55+
std::wstring message =
56+
L"{ \"kind\": \"event\", \"name\": "
57+
L"\"WebResourceResponseReceived\", \"args\": {"
58+
L"\"request\": " +
59+
RequestToJsonString(webResourceRequest.get()) +
60+
L", "
61+
L"\"response\": " +
62+
ResponseToJsonString(webResourceResponse.get()) + L"}";
63+
64+
message +=
65+
WebViewPropertiesToJsonString(m_webview.get());
66+
message += L"}";
67+
PostEventMessage(message);
68+
return S_OK;
69+
})
70+
.Get());
71+
72+
return S_OK;
73+
})
74+
.Get(),
75+
&m_webResourceResponseReceivedToken);
76+
```
77+
78+
## C#
79+
```c#
80+
WebView.WebResourceResponseReceived += WebView_WebResourceResponseReceived;
81+
82+
// Note: modifications made to request and response are ignored
83+
private async void WebView_WebResourceResponseReceived(object sender, CoreWebView2WebResourceResponseReceivedEventArgs e)
84+
{
85+
// Actual headers sent with request
86+
foreach (var current in e.Request.Headers)
87+
Console.WriteLine(current);
88+
89+
// Headers in response received
90+
foreach (var current in e.Response.Headers)
91+
Console.WriteLine(current);
92+
93+
// Status code from response received
94+
int status = e.Response.StatusCode;
95+
if (status == 200)
96+
{
97+
// Handle
98+
Console.WriteLine("Request succeeded!");
99+
100+
// Get response body
101+
try
102+
{
103+
await e.PopulateResponseContentAsync();
104+
DoSomethingWithResponseBody(e.Response.Content);
105+
} catch (Exception ex)
106+
{
107+
// An exception will be thrown if the request has no body.
108+
}
109+
}
110+
}
111+
```
112+
113+
114+
# Remarks
115+
Calling `PopulateResponseContent` will fail/throw an exception if the response
116+
has no body. An exception will also be thrown for redirect responses, for which
117+
the body (if any) is ignored.
118+
119+
120+
# API Notes
121+
See [API Details](#api-details) section below for API reference.
122+
123+
124+
# API Details
125+
## COM
126+
```cpp
127+
library WebView2
128+
{
129+
interface ICoreWebView2 : IUnknown
130+
{
131+
// ...
132+
133+
/// Add an event handler for the WebResourceResponseReceived event.
134+
/// WebResourceResponseReceived event fires after the WebView has received
135+
/// and processed the response for a WebResource request. The event args
136+
/// include the WebResourceRequest as sent by the wire and WebResourceResponse
137+
/// received, including any additional headers added by the network stack that
138+
/// were not be included as part of the associated WebResourceRequested event,
139+
/// such as Authentication headers.
140+
HRESULT add_WebResourceResponseReceived(
141+
[in] ICoreWebView2WebResourceResponseReceivedEventHandler* eventHandler,
142+
[out] EventRegistrationToken* token);
143+
/// Removes the WebResourceResponseReceived event handler previously added
144+
/// with add_WebResourceResponseReceived
145+
HRESULT remove_WebResourceResponseReceived(
146+
[in] EventRegistrationToken token);
147+
}
148+
149+
/// Fires when a response for a request is received for a Web resource in the webview.
150+
/// Host can use this event to view the actual request and response for a Web resource.
151+
/// This includes any request or response modifications made by the network stack (such as
152+
/// adding of Authorization headers) after the WebResourceRequested event for
153+
/// the associated request has fired. Modifications made to the request or response
154+
/// objects are ignored.
155+
interface ICoreWebView2WebResourceResponseReceivedEventHandler : IUnknown
156+
{
157+
/// Called to provide the implementer with the event args for the
158+
/// corresponding event.
159+
HRESULT Invoke(
160+
[in] ICoreWebView2* sender,
161+
[in] ICoreWebView2WebResourceResponseReceivedEventArgs* args);
162+
}
163+
164+
/// Completion handler for PopulateResponseContent async method. It's invoked
165+
/// when the Content stream of the Response of a WebResourceResponseReceieved
166+
/// event is available.
167+
interface ICoreWebView2WebResourceResponseReceivedEventArgsPopulateResponseContentCompletedHandler : IUnknown
168+
{
169+
/// Called to provide the implementer with the completion status
170+
/// of the corresponding asynchronous method call.
171+
HRESULT Invoke([in] HRESULT errorCode);
172+
}
173+
174+
/// Event args for the WebResourceResponseReceived event. Will contain the
175+
/// request as it was sent and the response as it was received.
176+
/// Note: To get the response content stream, first call PopulateResponseContent
177+
/// and wait for the async call to complete, otherwise the content stream object
178+
/// returned will be null.
179+
interface ICoreWebView2WebResourceResponseReceivedEventArgs : IUnknown
180+
{
181+
/// Web resource request object. Any modifications to this object will be ignored.
182+
[propget] HRESULT Request([out, retval] ICoreWebView2WebResourceRequest** request);
183+
/// Web resource response object. Any modifications to this object
184+
/// will be ignored.
185+
[propget] HRESULT Response([out, retval] ICoreWebView2WebResourceResponse** response);
186+
187+
/// Async method to request the Content stream of the response.
188+
HRESULT PopulateResponseContent(ICoreWebView2WebResourceResponseReceivedEventArgsPopulateResponseContentCompletedHandler* handler);
189+
}
190+
}
191+
```
192+
193+
## WinRT
194+
```c#
195+
namespace Microsoft.Web.WebView2.Core
196+
{
197+
runtimeclass CoreWebView2
198+
{
199+
// ...
200+
201+
/// WebResourceResponseReceived event fires after the WebView has received and processed the response for a WebResource request.
202+
event Windows.Foundation.TypedEventHandler<CoreWebView2, CoreWebView2WebResourceResponseReceivedEventArgs> WebResourceResponseReceived;
203+
}
204+
205+
/// Event args for the WebResourceResponseReceived event.
206+
runtimeclass CoreWebView2WebResourceResponseReceivedEventArgs
207+
{
208+
/// Web resource request object.
209+
/// Any modifications to this object will be ignored.
210+
CoreWebView2WebResourceRequest Request { get; };
211+
/// Web resource response object.
212+
/// Any modifications to this object will be ignored.
213+
CoreWebView2WebResourceResponse Response { get; };
214+
215+
/// Async method to request the Content stream of the response.
216+
Windows.Foundation.IAsyncAction PopulateResponseContentAsync();
217+
}
218+
}
219+
```

0 commit comments

Comments
 (0)