WebView使用loadUrl和loadData的区别造成的问题

在使用WebView时我们比较熟悉的加载html的两个方法,一个是loadUrl,另一个是loadData,这两个方法的函数签名分别是:

public void loadUrl(String url) 
public void loadData(String data, String mimeType, String encoding) 

这两个WebView函数由于加载时loadData方法实现存在一些问题,它无法支持一些特殊的标点符号进行判断处理,其实现和loadUrl差别巨大,因此会有一些很奇怪的问题出现。比如一段div当中插入一段带有行内style的span时,这个div居然会被截断,后面的内容不再显示。而通过loadUrl通过http服务加载完全相同的页面,则完全不会有渲染问题出现,因此loadData这个方法被我们弃用。后来发现有人说只要给这个页面渲染时加一个baseurl就可以正常渲染,需要用到WebView的另一个函数,函数签名为

    public void loadDataWithBaseURL(String baseUrl, String data,
            String mimeType, String encoding, String failUrl)

我们使用这个方法时跟loadData一样,String data参数还放数据,mimeType参数仍然传"text/html",encoding仍然传"utf-8",我们给baseUrl和failUrl传null或者""即可。loadDataWithBaseURL的实现和loadData不同,不会出现loadData拉跨的情况出现。因此建议使用loadDataWithBaseURL。

附录:
在官方文档中loadData的解释:

loadData
Added in API level 1

public void loadData (String data, 
                String mimeType, 
                String encoding)

Loads the given data into this WebView using a 'data' scheme URL.

Note that JavaScript's same origin policy means that script running in a page loaded using this method will be unable to access content loaded using any scheme other than 'data', including 'http(s)'. To avoid this restriction, use loadDataWithBaseURL() with an appropriate base URL.

The encoding parameter specifies whether the data is base64 or URL encoded. If the data is base64 encoded, the value of the encoding parameter must be "base64". HTML can be encoded with Base64.encodeToString(byte[], int) like so:

 String unencodedHtml =
     "<html><body>'%28' is the code for '('</body></html>";
 String encodedHtml = Base64.encodeToString(unencodedHtml.getBytes(), Base64.NO_PADDING);
 webView.loadData(encodedHtml, "text/html", "base64");
 

For all other values of encoding (including null) it is assumed that the data uses ASCII encoding for octets inside the range of safe URL characters and use the standard %xx hex encoding of URLs for octets outside that range. See RFC 3986 for more information. Applications targeting Build.VERSION_CODES.Q or later must either use base64 or encode any # characters in the content as %23, otherwise they will be treated as the end of the content and the remaining text used as a document fragment identifier.

The mimeType parameter specifies the format of the data. If WebView can't handle the specified MIME type, it will download the data. If null, defaults to 'text/html'.

The 'data' scheme URL formed by this method uses the default US-ASCII charset. If you need to set a different charset, you should form a 'data' scheme URL which explicitly specifies a charset parameter in the mediatype portion of the URL and call loadUrl(java.lang.String) instead. Note that the charset obtained from the mediatype portion of a data URL always overrides that specified in the HTML or XML document itself.

Content loaded using this method will have a window.origin value of "null". This must not be considered to be a trusted origin by the application or by any JavaScript code running inside the WebView (for example, event sources in DOM event handlers or web messages), because malicious content can also create frames with a null origin. If you need to identify the main frame's origin in a trustworthy way, you should use loadDataWithBaseURL() with a valid HTTP or HTTPS base URL to set the origin.

再看看loadDataBaseUrl方法的官方文档解释:

loadDataWithBaseURL
Added in API level 1

public void loadDataWithBaseURL (String baseUrl, 
                String data, 
                String mimeType, 
                String encoding, 
                String historyUrl)

Loads the given data into this WebView, using baseUrl as the base URL for the content. The base URL is used both to resolve relative URLs and when applying JavaScript's same origin policy. The historyUrl is used for the history entry.

The mimeType parameter specifies the format of the data. If WebView can't handle the specified MIME type, it will download the data. If null, defaults to 'text/html'.

Note that content specified in this way can access local device files (via 'file' scheme URLs) only if baseUrl specifies a scheme other than 'http', 'https', 'ftp', 'ftps', 'about' or 'javascript'.

If the base URL uses the data scheme, this method is equivalent to calling loadData() and the historyUrl is ignored, and the data will be treated as part of a data: URL, including the requirement that the content be URL-encoded or base64 encoded. If the base URL uses any other scheme, then the data will be loaded into the WebView as a plain string (i.e. not part of a data URL) and any URL-encoded entities in the string will not be decoded.

Note that the baseUrl is sent in the 'Referer' HTTP header when requesting subresources (images, etc.) of the page loaded using this method.

If a valid HTTP or HTTPS base URL is not specified in baseUrl, then content loaded using this method will have a window.origin value of "null". This must not be considered to be a trusted origin by the application or by any JavaScript code running inside the WebView (for example, event sources in DOM event handlers or web messages), because malicious content can also create frames with a null origin. If you need to identify the main frame's origin in a trustworthy way, you should use a valid HTTP or HTTPS base URL to set the origin.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值