-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathindex.html
916 lines (839 loc) · 46.1 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>WebView: Usage Scenarios and Challenges</title>
<script src="https://www.w3.org/Tools/respec/respec-w3c" class="remove" defer></script>
<script class="remove">
// All config options at https://respec.org/docs/
var respecConfig = {
specStatus: "CG-DRAFT",
editors: [{
name: "Qing An",
w3cid: "76701",
company: "Alibaba",
companyURL: "https://www.alibabagroup.com/en/global/home"
}, {
name: "Rayan Kanso",
company: "Google",
companyURL: "https://www.google.com/"
}],
github: "WebView-CG/usage-and-challenges",
xref: ["miniapp-packaging"],
group: "cg/webview",
};
</script>
</head>
<body>
<section id="abstract">
<p>This document aims to identify representative use cases of where WebViews are being used, regardless of the
platform and type of device they're used on, identify the issues that arise from these usages and determine
whether these issues can be addressed through improvements to the Web Platform, the surrounding ecosystem (e.g.
documentation, testing frameworks) or through other mechanisms.</p>
</section>
<section id="sotd">
<p>This is the skeleton of the core document on which the WebView Community Group will focus in its <a
href="https://github.com/WebView-CG/charter/blob/main/charter.md">first phase of work</a>.</p>
</section>
<section class="informative">
<h2>Introduction</h2>
<p>The WebView Community Group aims to identify, understand and reduce the issues arising from the use of software
components (typically referred to as [=WebViews=]) that are used to render Web technology-based content outside of
a Web browser (native applications, MiniApps, etc).</p>
<p>This document contains sections describing the use cases that were contributed by multiple authors. Since this
document is a group note, additional use cases will be added in future revisions of this document.</p>
</section>
<section class="informative">
<h2>WebViews</h2>
<p>A <dfn data-lt="native application|native app">native application</dfn> (or native <abbr
title="application">app</abbr>) is an application designed to run on a particular operating system. It is
written in native code and leverages native APIs exposed by the operating system. Typical examples include an iOS
application written in Swift or Objective-C and that uses the iOS <abbr
title="Software Development Kit">SDK</abbr>, or an Android application written in Kotlin, Java or C++ using the
Android SDK. [=native applications=] do not require a dedicated runtime to run as they interface with the
operating system directly.</p>
<p>A <dfn>web application</dfn> (or web app) is an application written using Web technologies (URLs, HTML, CSS,
JavaScript APIs). [=web applications=] typically run in a web browser runtime. All systems and devices that can
render Web content have at least one <dfn>system-wide Web browser</dfn> application, which is either pre-installed
on the device or that users can install.</p>
<p><dfn>WebViews</dfn> are software components provided in an SDK that can be used to render Web content directly
within a [=native application=] without having to switch to the [=system-wide Web browser=]. [=WebViews=] are used
in a wide range of scenarios. They all share the same architecture: a [=native application=] embeds and interacts
with one or more [=WebViews=] to render Web content within the [=WebView=].</p>
<section class="informative">
<h3>Types of WebViews</h3>
<p>[=WebViews=] can differ based on the following properties:</p>
<p>
<ul>
<li><dfn data-lt="UX flexibility|flexible"><abbr title="User Experience">UX</abbr> flexibility</dfn>: Whether
the [=native application=] has full control over the UX provided by the WebView or whether the WebView imposes
the UX with limited customization and control from the [=native application=].</li>
<li><dfn data-lt="Access to the web content|Access the web content">Access to the web content</dfn>: Whether the
[=native application=] has the ability to read and modify the web content rendered in the WebView. The native
application can leverage this to establish a communication link between the native code and the Web code, and
in particular to expose native APIs to the Web content, making it possible for the Web content to make native
calls.</li>
<li><dfn data-lt="State sharing|Share state">State sharing</dfn>: Whether the WebView shares state such as
cookies and cache with the [=system-wide web browser=], or is completely isolated.</li>
</ul>
</p>
<p>However, in practice, [=WebViews=] are classified into one of two categories with fixed properties:</p>
<dl>
<dt><dfn>Browser-like</dfn> WebViews</dt>
<dd>These WebViews are straightforward to embed with a simpler API surface mostly targeted at loading the web
page. They are generally not [=flexible=], do not provide [=access to the web content=], but [=share state=]
with the [=system-wide web browser=].</dd>
<dt><dfn>Fully-fledged</dfn> WebViews</dt>
<dd>These WebViews are used for creating richer experiences and feature powerful integration primitives. They
have full [=UX flexibility=] when integrated within an application, provide the ability to [=access the web
content=] (native and web parts of the application can communicate), and do not [=share state=] with the
[=system-wide web browser=].</dd>
</dl>
</section>
</section>
<section class="informative">
<h2>Implementations</h2>
<p>The following table contains different [=WebView=] implementations with their different considerations</p>
<table class="data">
<thead>
<tr>
<th>Category</th>
<th>Name</th>
<th>Platforms</th>
<th>Description</th>
<th>Features</th>
<th>Limitations</th>
<th>[=UX flexibility=]</th>
<th>Usage Example</th>
</tr>
</thead>
<tbody>
<tr>
<td>[=Fully-fledged=]</td>
<td>Android <code>WebView</code></td>
<td>Android</td>
<td>Default WebView implementation on Android</td>
<td>Apps have [=access to the web content=]</td>
<td>Same features as in Chrome overall but some Web APIs are not supported</td>
<td>WebView may be resized and mixed with native content</td>
<td>Hybrid Frameworks (Cordova, Capacitor)</td>
</tr>
<tr>
<td>[=Browser-like=]</td>
<td>Custom Tabs</td>
<td>Android</td>
<td>API for opening [=browser-like=] WebViews on Android</td>
<td>Browser navigation and convenience features like password autofill</td>
<td>No [=access to the Web content=]</td>
<td>Only minimal customization of the top bar possible</td>
<td>Link preview in social media Apps</td>
</tr>
<tr>
<td>[=Browser-like=]</td>
<td><code>SFSafariViewController</code></td>
<td>iOS, iPadOS</td>
<td>API for opening [=browser-like=] WebViews on iOS</td>
<td>Browser navigation and convenience features like password autofill</td>
<td>No [=access to the Web content=]</td>
<td>Only minimal customization of the top bar possible</td>
<td>Link preview in social media apps</td>
</tr>
<tr>
<td></td>
<td><code>UIWebView</code> (deprecated)</td>
<td>iOS, iPadOS, macOS</td>
<td>Soon-to-be-removed WebView API of iOS</td>
<td>Apps have [=access to the web content=]</td>
<td>Some Web standards are not supported. Performance and security wise inferior to <code>WKWebView</code>,
deprecated</td>
<td>WebView may be resized and mixed with native content</td>
<td>Hybrid Frameworks (Cordova, Capacitor)</td>
</tr>
<tr>
<td>[=Fully-fledged=]</td>
<td><code>WKWebView</code></td>
<td>iOS, iPadOS, macOS</td>
<td>Default WebView implementation on iOS</td>
<td>Apps have [=access to the web content=]</td>
<td>Same features as in Safari overall but some Web APIs are not supported</td>
<td>WebView may be resized and mixed with native content</td>
<td>Hybrid Frameworks (Cordova, Capacitor)</td>
</tr>
<tr>
<td>[=Fully-fledged=]</td>
<td><code>WebView2</code></td>
<td>Windows</td>
<td>Default WebView implementation on Windows</td>
<td>Apps have [=access to the web content=]</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<aside class="warning">
<p>This list of WebView implementations is not comprehensive. It is based on the information provided in <a
href="https://github.com/WebView-CG/usage-and-challenges/issues/19">#19</a></p>
</aside>
<aside class="note">
<p>TODO: Add column about state sharing</p>
</aside>
</section>
<section class="informative">
<h2>Usages</h2>
<dl>
<dt><dfn>Hybrid apps</dfn></dt>
<dd>
<p>[=Hybrid apps=] combine elements of [=native applications=] and [=web applications=].</p>
<p>[=Web applications=] wrapped in a native container are an example of an [=hybrid app=]. This provides
developers with a cross-platform mechanism to build a [=native application=]. When [=fully-fledged=] WebViews
are used, the ability to [=access the web content=] may be leveraged to add native-like capabilities to the
WebView.</p>
<p>Another example is In-App Browsers (IABs), which is a pattern for browsing links to web pages within a native
application without leaving the application.</p>
</dd>
<dt>Browsers</dt>
<dd>WebViews may be used to build browsers since they provide the capabilities of a rendering engine. When done
with [=fully-fledged=] WebViews, these browsers can provide more customizable experiences (e.g. privacy-focused
browsers) by modifying the web content.</dd>
<dt>Mini apps & super apps</dt>
<dd>
<p>WebViews may be used to render the web content of a [=MiniApp=] page.</p>
<p>Features that are not supported by the WebView, or that run with limited performance (such as maps, videos,
etc.), are typically replaced by native components that take care of the rendering.</p>
<p>For these reasons, [=fully-fledged=] WebViews are used in the [=MiniApp=] ecosystem, to allow for [=UX
flexibility=] and [=access to the web content=].</p>
</dd>
</dl>
</section>
<section class="informative">
<h2>Limitations & Challenges</h2>
<p>Individual limitations and challenges linked to specific usage scenarios are detailed in <a
href="#scenarios"></a>. The following themes have emerged:</p>
<dl>
<dt>Performance</dt>
<dd>Responsiveness is a critical requirement for applications. There are multiple opportunities to improve WebView
performance, such as for initialization and page loads.</dd>
<dt>Inconsistencies</dt>
<dd>Behavioral inconsistencies across different WebViews diminish the interoperability of the web since web
experiences will have to be special-cased against WebViews.</dd>
<dt>Control</dt>
<dd>Especially for [=fully-fledged=] WebViews, some user journeys are unachievable without additional control over
the web content and rendering engine.</dd>
<dt>Security and Privacy</dt>
<dd>[=fully-fledged=] WebViews ship with powerful APIs that provide [=access to the web content=] without
following usual web security restrictions. This unlocks powerful integration scenarios but can also be used for
malicious purposes such as tracking and phishing.</dd>
</dl>
</section>
<section class="appendix">
<h2>Scenarios</h2>
<section>
<h2>Load a WebView Page</h2>
<dl>
<dt>Submitter(s)</dt>
<dd>
Qing An, Alibaba
</dd>
<dt>Motivation</dt>
<dd>
It is quite common to use WebView in Native App development, due to WebView’s benefit of cross-platform
interoperability. But the page loading performance of WebView cannot satisfy Native App well, which means the
loading of a WebView page is quite slower than loading a Native page.
<br>
<br>
The below is WebView page loading, it firstly shows the white screen.
<figure>
<img alt="WebView page loading" src="./images/Load-WebView-Page.gif" width="400">
<figcaption>
WebView page loading
</figcaption>
</figure>
But for the Native page loading as shown below, it shows the skeleton immediately, which gives a better user
experience compared with WebView.
<figure>
<img alt="Native page loading" src="./images/Load-Native-Page.gif" width="400">
<figcaption>
Native page loading
</figcaption>
</figure>
Therefore, how to enhance the loading performance of WebView page needs to be addressed.
</dd>
<dt>Stakeholders</dt>
<dd>
<ul>
<li>WebView provider: browsers, deciders on how to enhance WebView</li>
<li>WebView user: Native App or MiniApp which rely on WebView to render pages</li>
<li>End user: users of the Native App or MiniApp are indirectly using the pages and functions implemented by
WebView</li>
</ul>
</dd>
<dt>Analysis</dt>
<dd>
The reason of long white screen is due to serial execution in loading a WebView page. The duration of white
screen directly depends on the time cost from routing intercept to JS download & parse & exec as described in
the following figure.
<figure>
<img alt="Procedure of loading a WebView page" src="./images/Procedure-of-loading-a-webview-page.png"
width="800">
<figcaption>
Procedure of loading a WebView page
</figcaption>
</figure>
</dd>
<dt>Related W3C deliverables and/or work items</dt>
<dd>
<ul>
<li><a href="https://www.w3.org/TR/resource-hints/">Resource Hints</a> defines the Prefetch on page
resources</li>
<li><a href="https://www.w3.org/TR/preload/ ">Preload</a> defines provides a declarative fetch primitive
that initiates an early fetch and separates fetching from resource execution</li>
</ul>
</dd>
<dt>How is the issue solved in the Browser, and what’s more is needed?</dt>
<dd>
<ul>
<li>In the Browser: Prefetch, Preload and Next are used to pre-request resources (e.g. HTML, CSS,
JavaScript, Img, etc.), but they are not supported or only partly supported by WebView.</li>
<li>What’s more: how to pre-request the data (JSON, XML, etc.)
<br>
Take e-commerce App as example. WebView is used to render the page of product list and product info. So, a
request to fetch the data is needed, and the data is described and transferred in the format of JSON or
XML. Sometimes, user info is also carried in the request, to obtain the personalized product info. If the
data can be pre-requested, the performance of loading a product page can be increased.
</li>
</ul>
</dd>
</dl>
</section>
<section>
<h2>Requests/responses sharing and proxy between Native and WebView</h2>
<dl>
<dt>Submitter(s)</dt>
<dd>
John Riviello
<br>
Jiasheng Wu, ByteDance
</dd>
<dt>Motivation</dt>
<dd>
In a hybrid Native/WebView app, some Native app may load first-party website or third-party website through
WebView. So, the Native app and the WebView may make the exact same calls in first-party business, or Native
app handles the resource request on behalf of WebView and the corresponding response data returned to WebView
can even be different with what is received by Native from the backend server. Also, not all requests want to
be proxied through Native, WebView user want to proxy a small number of requests locally to load offline
resources.
<br>
<br>
Some scenarios:
<ol>
<li>Document access control: it is expected to manage the access control of Web access documents, allowing
different users to access documents of different levels.</li>
<li>Security firewall: In order to meet compliance requirements, network engineers want to audit requests
within the app, and do not allow insecure requests to be sent on the web.</li>
<li>Transcoder: In special scenarios, we may need to convert GIF images to JPEG images to send to reduce
traffic, and may also need to translate documents to meet communication needs in different language
scenarios. For example, it's hard for a user to communicating in English. When communicating, the user can
type Chinese and it will be automatically translated into English.</li>
<li>Anonymous: Some users may have higher requirements for the privacy of Web access, requiring that
requests within the Web must remove identity features (such as client IP address, From header, Referer
header, cookie, URI session ID), providing a high degree of privacy and anonymity.</li>
<li>Reducing network requests: A hybrid app (in the sense that some screens are native code and other
screens are Webviews) may make some of the same network requests (HTTP GET, POST, PUT, DELETE, or other
network connections supported by webviews such as Web Sockets and WebRTC) in both the native screens and
the webview screens. Being able to easily share those responses between native and web (while maintaining
proper HTTP cache semantics) would reduce redundant requests, saving end-users bandwidth and reducing
server traffic.</li>
</ol>
<aside class="note">
<p>
The open questions on handling CORS (Cross-Origin Resource Sharing) & whether we should distinguish access
between first-party and third-party content needs to be further considered.
</p>
</aside>
</dd>
<dt>Stakeholders</dt>
<dd>
<ul>
<li>WebView provider: Apple, Google, deciders on how to enhance sharing between WebView & Native</li>
<li>WebView user: Native Business rely on WebView to send internal request, or load offline resource</li>
<li>End user: users of the App save bandwidth by not having to make duplicate calls</li>
</ul>
</dd>
<dt>Analysis</dt>
<dd>
This is currently even possible in some way, but it is not a recommended pattern. So making this a standard
that is easy to use for both Native and WebView developers would be a win for both groups.
<br>
<br>
<a
href="https://developer.android.com/reference/android/webkit/WebViewClient#shouldInterceptRequest(android.webkit.WebView,%20android.webkit.WebResourceRequest)">shouldInterceptRequest</a>
in Android WebView provide develop with optional network interception capability.
</dd>
<dt>Related W3C deliverables and/or work items</dt>
<dd>
N/A
</dd>
<dt>How is the issue solved in the Browser, and what’s more is needed?</dt>
<dd>
N/A
</dd>
</dl>
</section>
<section>
<h2>Render WebView Components and Native Components in same layer</h2>
<dl>
<dt>Submitter(s)</dt>
<dd>
Qing An, Alibaba
</dd>
<dt>Motivation</dt>
<dd>
Hybrid Native/Webview App and MiniApp often use both WebView Components (text, label, button, image, etc.) and
Native Components (such as video).
<ol>
<li>Add a map: due to that developing a Web-based map component is difficult and not so good performance,
developers may choose to use the Native map component. Usually, developers cover the WebView with the
Native map component. But very often, the Native map will cover all the Web components rendered by
WebView. And it is difficult to display one or several Web components on the Native map.</li>
<li>Integrate a third-party content into WebView: from the business perspective, Native App needs to
integrate third-party advertisements into the some App UI pages which are rendered by WebView. Many
third-party advertisements are implemented based on Native components. How to integrate Native components
with WebView smoothly?</li>
<li>WebView interacts with Native component: developers have implemented a fancy UI page based on WebView,
and then the WebView needs to use an extra Native component. How can the Native component interact with
WebView smoothly? Like how to let Native component reuse the event handling and message interaction that
have been implemented in WebView?</li>
</ol>
Unlike WebView Components, the Native Components are rendered by Native App instead of WebView. While Native
Components can bring more features by complementing WebView Components, Native Components also bring issue for
developers due to that Native rendering is independent of WebView rendering.
<br>
<br>
Therefore, Native Component cannot be controlled by z-index property, and cannot overlap with WebView
components, as illustrated below.
<figure>
<img alt="Without-same-layer-rendering" src="./images/Without-same-layer-rendering.png" width="400">
<figcaption>
Render WebView Components and Native Components in separate layers
</figcaption>
</figure>
But if the Native Components can be rendered in the same layer of WebView Component, AKA in the WebView Layer,
developers can easily control the Native Components as well as the overlapping with other WebView Components,
as illustrated below.
<figure>
<img alt="With-same-layer-rendering" src="./images/With-same-layer-rendering.png" width="400">
<figcaption>
Render WebView Components and Native Components in same layer
</figcaption>
</figure>
</dd>
<dt>Stakeholders</dt>
<dd>
<ul>
<li>WebView provider: Apple, Google, deciders on how to support the same layer rendering</li>
<li>Native App or MiniApp developer: rely on the WebView</li>
<li>End user: users of the Native App or MiniApp are indirectly using the pages and functions implemented by
WebView.</li>
</ul>
</dd>
<dt>Analysis</dt>
<dd>
Currently, Native rendering is independent of WebView rendering. Therefore, Native Component cannot be
controlled by `z-index` property, and cannot overlap with WebView components.
</dd>
<dt>Related W3C deliverables and/or work items</dt>
<dd>
N/A
</dd>
<dt>How is the issue solved in the Browser, and what’s more is needed?</dt>
<dd>
N/A
</dd>
</dl>
</section>
<section>
<h2>Inject custom JS scripts</h2>
<dl>
<dt>Submitter(s)</dt>
<dd>
Maxim Tsoy, Duck Duck Go
</dd>
<dt>Motivation</dt>
<dd>
User scripts (aka content scripts) is a powerful tool that unlocks many possibilities such as:
<ul>
<li>content customization (e.g. applying custom CSS, adding UI elements)</li>
<li>security and privacy protection (e.g. blocking harmful APIs, preventing data leakage and fingerprinting)
</li>
<li>enriching web app functionality (e.g. filling previously saved passwords, translating text to foreign
language, polyfilling missing APIs)</li>
</ul>
Injected scripts can also be a workaround when another WebView feature is not available: for example, due to
the lack of granular cookie control in native WebView APIs, one method is to <a
href="https://github.com/duckduckgo/content-scope-scripts/blob/main/src/features/cookie.js">inject a
script</a> to augment `document.cookie API`.
</dd>
<dt>Stakeholders</dt>
<dd>
<ul>
<li>WebView vendors: Google (WebView), Microsoft (WebView2), Apple (WKWebView)</li>
<li>App developers that need customizations of the rendered content</li>
</ul>
</dd>
<dt>Analysis</dt>
<dd>
Web extensions have a similar concept of <a
href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts">content
scripts</a>, however the features provided by the native WebView implementaions are much less versatile and
not standardized.
<br>
<br>
Most platforms implement a basic `evaluateJS(<string_payload>)` kind of method, which allows to execute
arbitrary JS code in the page context. However, it is limited, and lacks some important features that would
make developers live easier if they were cross-platform:
<ol>
<li><b>Run scripts in isolated world</b>
<br>
It is common for web pages to change JS prototypes and global variables. This can easily affect the
scripts injected by the native app. This can lead to security and privacy issues, and is very hard to
prevent. <a
href="https://developer.chrome.com/docs/extensions/mv3/content_scripts/#isolated_world">Isolated
world</a> prevents these collisions by running the content script within its own JS environment, while
still allowing it to access the DOM. Moreover, scripts in isolated world are not affected by CSP and
other restrictions imposed on the page scripts.
<aside class="note">
<p>Isolated world is not a replacement to the main world</p>
<p>Isolated world (called "content world" there) is available on <a
href="https://developer.apple.com/documentation/webkit/wkcontentworld">Apple platforms</a>;
Android and Windows WebViews can only execute code in the page context ("main" world)</p>
</aside>
</li>
<li><b>Inject scripts in all iframes, including cross-origin and sandboxed ones</b>
<br>
This is currently a serious limitation on Android, which only allows executing in same-origin contexts.
For DuckDuckGo browsers, this makes it very difficult to apply tracking protections, since trackers
often operate in a third-party context.
</li>
<li><b>Inject scripts before all page scripts</b>
<br>
Web extensions have a <a
href="https://developer.chrome.com/docs/extensions/mv3/content_scripts/#run_time">"run_at"</a>
paramenter that controls when the script will be executed. This is crucial for any security and privacy
customizations that need to apply protections before any malicious script can take effect. For example,
<a
href="https://github.com/duckduckgo/content-scope-scripts/blob/main/src/features/fingerprinting-screen-size.js">anti-fingerprinting
protection</a> augments the APIs, but it only protects from scripts executed after it.
<br>
<a href="https://developer.apple.com/documentation/webkit/wkuserscriptinjectiontime">WKWebView</a> and
<a
href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.web.webview2.core.corewebview2.addscripttoexecuteondocumentcreatedasync?view=webview2-dotnet-1.0.1245.22">WebView2</a>
can do this (although API approaches are different), but Android WebView doesn't allow it
</li>
<li><b>Secure messaging between the native code and injected scripts</b>
<br>
Content scripts often work in combination with the native components and so require communication. For
example, in DuckDuckGo browsers scripts use this to read user configuration (which is managed by the
Native App), and trigger native UI changes on page-generated events.
<br>
WKWebView provides a <a
href="https://developer.apple.com/documentation/webkit/wkscriptmessagehandlerwithreply">convenient
API</a> for passing async messages, but Android WebView and Windows WebView2 do not have an
alternative. It is possible to achieve a one-way communication by exposing global JS callables, but
without isolated world this is insecure, since page scripts would be able to use those globals too.
</li>
<li><b>Inject scripts in ServiceWorkers and (Shared) Web Workers</b>
<br>
Some scripts are designed to change the JS environment of the page scripts. For example, DuckDuckGo
cookie protection <a
href="https://github.com/duckduckgo/content-scope-scripts/blob/main/src/features/cookie.js">deliberately
changes</a> the `document.cookie` API to protect against long-lived tracking cookies. However, there
is currently no (straightforward) way to do this in Workers, which have access to powerful APIs as well
(e.g. <a href="https://developer.mozilla.org/en-US/docs/Web/API/Cookie_Store_API">Cookie Store API</a>)
<br>
This is currently not possible on any platform
</li>
</ol>
</dd>
<dt>Related W3C deliverables and/or work items</dt>
<dd>
<a href="https://github.com/w3c/webextensions">WebExtensions CG</a>
</dd>
<dt>How is the issue solved in the Browser, and what’s more is needed?</dt>
<dd>
In browsers, many of these issues are solved by Web Extension API. A lot of design patterns could be (and
already are) borrowed from there. WKUserScript is clearly inspired by, and probably built upon the same
technology.
<br>
However, just exposing the WebExtensions API might not always be the right solution: WebViews are embedded in
Native Apps, which operate and protect under a different security and performance model. In general, WebView
should probably give more raw control than WebExtensions API.
</dd>
</dl>
</section>
<section>
<h2>Control API permissions</h2>
<dl>
<dt>Submitter(s)</dt>
<dd>
Maxim Tsoy, Duck Duck Go
</dd>
<dt>Motivation</dt>
<dd>
In apps that can load arbitrary web apps, such as WebView-powered browsers, it is desirable to give users
control over website permissions via custom native UI. For example, a browser can prompt a user to allow a web
app to access the camera, and then show an indicator while it's being used. To allow browsers to manage
permissions, we need WebView APIs to:
<ul>
<li>List what permissions have been set for a given site (allow/deny/query)</li>
<li>Programmatically change and reset them</li>
<li>Receive events when a permission is requested or used</li>
</ul>
Some examples of permissions include:
<ul>
<li>camera / microphone</li>
<li>geolocation</li>
<li>screen capture</li>
<li>other permissions managed with <a
href="https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API">Permissions API</a></li>
</ul>
</dd>
<dt>Stakeholders</dt>
<dd>
<ul>
<li>WebView vendors (Google, Microsoft, Apple)</li>
<li>Browser vendors (e.g. DuckDuckGo)</li>
</ul>
</dd>
<dt>Analysis</dt>
<dd>
There's currently no cross-platform approach and support. Most WebViews provide events / APIs for specific
permissions, but the feature parity could be better.
<br>
Some specific examples of limitations:
<ul>
<li>Webkit has ways to control microphone and camera, but doesn't support Geolocation</li>
<li>Microsoft's WebView2 support is limited:
<ul>
<li><a href="https://github.com/MicrosoftEdge/WebView2Feedback/issues/2427">Feature request: Permissions
API</a></li>
<li><a href="https://github.com/MicrosoftEdge/WebView2Feedback/issues/2428">Feature request: Device or
permission "in use" event</a></li>
<li><a href="https://github.com/MicrosoftEdge/WebView2Feedback/issues/2442">Feature request: API for
screen sharing</a></li>
</ul>
</li>
<li>Android WebView could use some WebRTC-related events: <a
href="https://github.com/duckduckgo/Android/issues/429">WebRTC IP leak</a></li>
</ul>
</dd>
<dt>Related W3C deliverables and/or work items</dt>
<dd>
<a href="https://github.com/w3c/permissions/">Permissions API</a>
</dd>
<dt>How is the issue solved in the Browser, and what’s more is needed?</dt>
<dd>
Non-webview Browsers have implement this using internal APIs.
</dd>
</dl>
</section>
<section>
<h2>Manage web storage and cookies</h2>
<dl>
<dt>Submitter(s)</dt>
<dd>
Maxim Tsoy, Duck Duck Go
</dd>
<dt>Motivation</dt>
<dd>
Apps loading 3rd-party web content in WebViews may need more granular control over stored data. For example,
DuckDuckGo browsers need this for the Fireproof feature, which allows to make exceptions to the cookie/storage
removal.
</dd>
<dt>Stakeholders</dt>
<dd>
<ul>
<li>Browsers based on WebView</li>
<li>WebView vendors</li>
</ul>
</dd>
<dt>Analysis</dt>
<dd>
<ul>
<li>Webkit provides APIs to retrieve cookies and local/sessionStorage as opaque tokens that can be filtered
by hostname. This allows selective removal, although it requires some extra code and workarounds to
prevent timing issues (removal is asynchronous).</li>
<li>In Webkit, storage is shared between all WKWebView instances, unless it's "non persistent" (in memory),
which is not ideal for building web browsers.</li>
<li>In Android WebView, it is not possible to inspect cookie scopes. You can retrieve cookie names and
values, but without knowing other attributes it is impossible to override them properly.</li>
<li>Android WebView does not provide APIs to manage localStorage/sessionStorage.</li>
</ul>
</dd>
<dt>Related W3C deliverables and/or work items</dt>
<dd>
N/A
</dd>
<dt>How is the issue solved in the Browser, and what’s more is needed?</dt>
<dd>
Browsers manage storage using APIs of a specific rendering engine.
</dd>
</dl>
</section>
<section>
<h2>The Origin in a WebView for locally hosted content</h2>
<dl>
<dt>Submitter(s)</dt>
<dd>
Niklas Merz, Apache Software Foundation
</dd>
<dt>Motivation</dt>
<dd>
WebViews are widely used for building apps on the dominating mobile and desktop platforms. <a
href="https://appfigures.com/top-sdks/development/all">Up to 30%</a> of apps found in the app stores (Apple
and Google) are built with frameworks like <a href="https://cordova.apache.org">Apache Cordova</a> and <a
href="https://capacitorjs.com/">CapacitorJS</a>. Those two frameworks use one big WebView for providing app
developers a native wrapper and some plugins for their Web app. App developers build their Web application and
put the HTML, CSS and JavaScript files in one folder. The framework then takes care of building a native app
project and bundling the Web code as a native application ready to distribute via the app stores.
<br>
App developers usually only need knowledge in HTML, CSS and JavaScript and can call native OS features via
plugins. The frameworks provide a bridge that makes these native features available as JavaScript functions
inside the WebView. Because of this, the locally hosted Web application "should just work as published on the
Web". Connections to the backend are usually done via fetch/XHR. Because the origin for the app code is
different than the backend, there is always CORS involved.
<br>
Cordova used to host the bundled Web content via `file://` URLs for a long time. In recent years many apps
needed to switch to a "proper origin" mainly because of two reason:
<ol>
<li>Web frameworks like React or Angular use their own router framework that relies on the origin and paths.
The just don't work with file URLs.</li>
<li>HTTP requests from file URLs have quirks in the CORS handling. If I recall correctly the WebViews
started to set the `Origin` HTTP header to `null` which made it difficult to make requests to backends and
APIs.</li>
</ol>
Therefore Capacitor and Cordova changed the defaults to hosting the content on their "special origins" based
on the fact that Android `https:://custom` and iOS `custom:\\custom` are using different approaches for their
origins in WebViews.
<ul>
<li>Android has <a
href="https://developer.android.com/reference/androidx/webkit/WebViewAssetLoader">WebViewAssetLoader</a>
that lets you create a "fake" domain to serve files to the WebView. Therefore, you can access local files
via `https://myappcode/index.html` for example. WebViewAssetLoader only allows you to serve GET requests
and access to the HTTP request is limited.</li>
<li>iOS lets you implement a custom URL scheme like `myapp://mycode` and you can access the HTTP request and
response quite freely to implement custom logic around that. This is called <a
href="https://developer.apple.com/documentation/webkit/wkurlschemehandler">WKURLSchemehandler.</a></li>
</ul>
</dd>
<dt>Stakeholders</dt>
<dd>
<ul>
<li>WebView providers: Apple, Google, deciders on how to support having a standardized origin of web content
hosted by the App for the Webview</li>
</ul>
</dd>
<dt>Analysis</dt>
<dd>
Apps built with this hybrid approach in mind are really dependent on making CORS work and HTTP requests
possible on their own web content. This approach might benefit from a standardized way of providing Web
content from the app to the WebView. This content could be considered secure.
<br>
The most promiment implementations in Android and iOS provided solutions for many problems and solved some of
those mentioned. But there still exist some issues. Some of them are:
<ul>
<li>With some backends it might cause problems that you need to allow two different origins for CORS.
Android only allows `http(s):` with WebViewAssetLoader and iOS only `custom:` etc with WKURLSchemeHandler.
So you can't have one static allow setting for CORS but <b>need its to be dynamic or the backend needs to
allow multiple origins.</b> (Some backends might not allow this.)</li>
<li><b>Anti tracking features of WebViews might block authentication cookies.</b> Most Apps have gotten rid
of cookies for good but sometimes cookies are still used. Especially iOS implemented a stronger
Intelligent Tracking Prevention in WebViews that blocks many cookies on CORS requests. In some cases even
<a href="https://bugs.webkit.org/show_bug.cgi?id=213510">legitimate authencation cookies to the apps
backend can get blocked</a> and developers either need to switch to a different authentication method if
possible or find workarounds.</li>
<li><b>Androids and iOS implementations of this "custom scheme API" are quite different.</b> iOS
WKURLSchemeHandler is quite powerful. As an app developer you can use the scheme handler for your custom
scheme like `app://custom` in many different ways to intercept HTTP requests from the WebView and provide
a custom response. From providing local files to proxying requests in the native layer everything is
possible. Androids WebViewAssetLoader is more limited with only loading local files in mind. If you
implement a custom domain you can mostly provide content to GET requests but your access to the request
and response of the HTTP request is limited.</li>
<li>The options to allow/deny traffic to Web content in in Webviews are not really standardized as well. iOS
has App Bound Domains but this has it's own capabilities and limitations.</li>
</ul>
So, maybe a standardized APIs for Webviews to load content not found on the Web but provided to the Webview on
a "proper origin" can solve this challenge.
</dd>
<dt>Related W3C deliverables and/or work items</dt>
<dd>
N/A
</dd>
<dt>How is the issue solved in the Browser, and what`s more is needed?</dt>
<dd>
N/A
</dd>
</dl>
</section>
<section>
<h2>Define different types of WebViews</h2>
<dl>
<dt>Submitter(s)</dt>
<dd>
Niklas Merz, Apache Software Foundation
</dd>
<dt>Motivation</dt>
<dd>
As more and more use cases are discussed, it might be helpful to define and name the different uses of
WebViews. WebViews can be used in many different ways and some of them are vastly different in terms of
privacy and security implications. It could be a good idea to separate them into different categories to
discuss them better.
</dd>
<dt>Stakeholders</dt>
<dd>
<ul>
<li>Browsers vendors</li>
<li>App developers</li>
</ul>
</dd>
<dt>Analysis</dt>
<dd>
We can already see these different categories of WebViews with the APIs available on the two big mobile
platforms. Android offers a powerful WebView API and <a
href="https://developer.chrome.com/blog/custom-tabs-android-11/">Chrome Custom Tabs</a>. iOS has WKWebView
for a rich WebView API and <a
href="https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller"><code>SFSafariViewController</code></a>
for a more browser-like experience embedded in native Apps.
<br>
The WebView APIs offer powerful features for example injecting JavaScript or other interactions with the pages
loaded into the WebView. These features require the designers of the WebView APIs and App developers to think
a lot about the security and privacy implications of their design choices. WebViews that allow the user to
navigate the Web freely need to be much more secure and restricted than WebViews that just allow code under
control of the App developers.
<br>
WebViews are used a lot to build the UI or core features of Apps. These Apps could benefit from more control
over the native parts of the App or vice versa the native code might want to have more control over the Web
content.
<br>
The distinction between browser-like WebViews and full WebViews embedded into Apps is the most obvious one but
there are many more like we see with ePub and <a
href="https://www.w3.org/TR/mini-app-white-paper/">MiniApps</a>.
<br>
If there are different types of WebViews with different use cases and feature sets App developers could
benefit from more freedom or security and privacy. Browser vendors could roll out powerful features for
developers of Apps built around WebViews but still keep the browsers and browser-like WebViews secure.
</dd>
<dt>Related W3C deliverables and/or work items</dt>
<dd>
N/A
</dd>
<dt>How is the issue solved in the Browser, and what’s more is needed?</dt>
<dd>
WebViews and browsers currently always have the same features and restrictions. Different WebView
implementations share different APIs to interact with the WebView content.
</dd>
</dl>
</section>
</section>
</body>
</html>