美文网首页
WebView问题

WebView问题

作者: fyg | 来源:发表于2020-08-10 11:43 被阅读0次

    1,跨域访问cookie

    是什么域名(domain)?

    域名主体
    也就是域名的名字,例如www.souhu.com网的域名主体就是 souhu。相同后缀的域名主体不能重复。
    
    

    域名级别规则

    顶级域名 一级域名 二级域名 三级域名什么区别?

    跨域访问
    跨域问题

    web是如何实现跨域的

    跨域

    android webview cookie (遇到的坑,终极方案,解决你的疑惑)

    AndroidWebview里设置Cookie遇到的坑

    
    注:这里一定要注意一点,在调用设置Cookie之后不能再设置
    
    webView.getSettings().setBuiltInZoomControls(true);  
    webView.getSettings().setJavaScriptEnabled(true);  
    
    这类属性,否则设置Cookie无效。
    

    WebView 正确设置cookie 的方法

    Android cookies正确的更新方式

    cookie中默认就是以分号分割的
    比如你写入这样的cookie
    
    String cookie = "name=cookie;year=2015";
    setCookie("http://xxx.xxx",cookie);
    那其实只把name=cookie写入到了http://xxx.xxx这个域名下,为什么year=2015没有写入呢,因为分号“;”是cookie默认的分割符,cookie认为出现“;”当前的cookie的值就结束了。
    那能不能不使用“;”去;连接字符串呢?
    正确的方式应该是怎么样的呢?
    使用base64转码一下就可以了,这样做你还能把信息加密一次,当然需要你跟h5的同学沟通一下,他那边拿到cookie的值需要base64一下,这样就完美了
    
    

    代码设置

    
    
    public static void syncCookie(X5WebView webView,Context context) {
            CookieSyncManager.createInstance(context);
            CookieManager cookieManager = CookieManager.getInstance();
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                if (webView == null) return;
                cookieManager.setAcceptThirdPartyCookies(webView,true);
            } else {
                cookieManager.setAcceptCookie(true);
            }
            if (UserInfoManager.isLoginState()){
                cookieManager.setCookie(DOMAIN_NAME, "token="+UserInfoManager.getUserToken());
            }
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                CookieSyncManager.getInstance().sync();
            }else{
                CookieManager.getInstance().flush();
            }
    
        }
    
    
    
        /**
         * 该方法有风险会清除掉别人设置的cookie
         * @param context
         */
        public static void removeCookie(Context context) {
            CookieSyncManager.createInstance(context);
            CookieManager cookieManager = CookieManager.getInstance();
            cookieManager.removeAllCookie();
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                CookieSyncManager.getInstance().sync();
            }else{
                CookieManager.getInstance().flush();
            }
        }
    
    
    

    DOMAIN_NAME 设置成如下:

    domain.png

    这样设置后 所有一级域名为baidu.com的 都可以访问

    2,HTTP和HTTPS 混合调用问题

    3,onJsAlert导致页面死机问题

    
            @Override
            public boolean onJsAlert(WebView view, String url, final String message, JsResult result) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (!mActivity.isFinishing()) {
                            CustomListDialog dialog = new CustomListDialog(mActivity);
                            dialog.setMessage(message);
                            dialog.show();
                        }
                    }
                });
                result.confirm();
                return true;
            }
    
    如上代码中一定要调用 result.confirm(); 或result.cancel(); 方法不然,页面弹出对话框后在次操作会无效
    
    

    android webview onJsAlert 注意事项

    4,onPageStarted(WebView view, String url, Bitmap favicon) 和 onPageFinished(WebView view, String url) 并非成对调用

    在两方法内手动控制按钮的显示与隐藏在某场景下有问题,
    比如: onPageStarted方法中显示,onPageFinished方法中隐藏 (具体场景忘记了,时间长了再写总结就很容易产生这样的问题,可能是重定向导致的)

    解决方案如下,改用 onProgressChanged 方法来完成:

    
    private WebChromeClient mWebChromeClient = new WebChromeClient() {
    
            private int mLastProgress = 0;
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                super.onProgressChanged(view, newProgress);
    
                if (newProgress >= 100 && mLastProgress != newProgress) {
                    mLastProgress = newProgress;
                    mWebSettings.setBlockNetworkImage(false);
                    shareIsVisible(view.getUrl(),mWebViewHelper.shareButtonHiddenCallBack);
    
                }
                mLastProgress = newProgress;
            }
    }
    

    android 关于webview onPageStarted调用两次
    WebView 重定向行为导致的多次加载问题
    android webView onPageFinish调用多次??(未解决)

    5, WebView 加载重定向页面无法后退解决方案

    首先说下问题,初始页面为A,点击某个链接跳转到B,B页面重定向到C页面 当调用webview.goBack()时,页面回退到B,然后接着会重定向回C页面. 导致 无法回退到A 页面,同时当前页面也不会关闭掉,参考了京东app后发现左上角有个关闭按钮,所以当时的临时方案为 当用户多次无法退出时,为用户提供 关闭按钮让用户关闭当前页面



    Android WebView 因重定向无法正常goBack()解决方案

    ----解决方案----
    android WebView 加载重定向页面无法后退解决方案

    webview重定向终极解决方案

    6,webview上传图片功能

    当时做一元夺宝需求时,用户可以评价嗮单并上传图库图片到网页,所以当时定的有两种方案:
    1,javascript方法+base64图片
    2,用webview自带的上传图片功能

    7,webview 解决证书无效问题

            @Override
            public void onReceivedSslError(WebView webView, SslErrorHandler sslErrorHandler, SslError sslError) {
                sslErrorHandler.proceed();
            }
    

    8, webview调用支付宝网页支付时,url中不可添加自定义参数,否则会显示页面无效,去掉自定义参数就可以了,支付宝网页支付时可以会对url 进行鉴权。

    
           @Override
           public boolean shouldOverrideUrlLoading(WebView view, String url) {
    
               if (!TextUtils.isEmpty(url) && url.contains(XXX_PREFIX_URL)) {
                   Uri uri = Uri.parse(url);
                   uri = uri.buildUpon().appendQueryParameter(KEY_DEEPLINK, DEEPLINK_HIDE).build();
                   mWebView.loadUrl(uri.toString());
                   mStartTime = System.currentTimeMillis();
                   return true;
               }
               mStartTime = System.currentTimeMillis();
               return false;
           }
    

    shouldOverrideUrlLoading

    9,WebView 过滤规则拦截导致的 黑屏或白屏

    https://mlogin.jiuxian.com/user/login?retUrl=https://mmember.jiuxian.com/club/clubPay
    

    webview未打开过 ,在首页打开(需要登录的)webView页面url1,此时页面发现未登录,会重定向到ur2?param=returl页 ,此时我拦截(shouldOverrideUrlLoading方法中的参数),也就是url2页面中的 returl参数值后,跳转到原生登录页,shouldOverrideUrlLoading方法返回true,登录页点击返回 ,返回到webView页面,此时这个页面显示黑屏。(由于拦截了该页面,当登录页点击返回的时候,应关闭webView页面)
    解决方法:

    原因:
    当你点击一个页面中一个链接时会经过shouldOverrideUrlLoading 方法 该方法 return true时,你可以自己来处理这个url,webview则不再处理这个url;return false时,webview来处理这个url。
    通俗的说,当返回true时,你点任何链接都是失效的,需要你自己跳转。return false时webview会自己跳转

    10,webView 拦截SCHEME自定义操作

    shouldOverrideUrlLoading(WebView view, String url) 方法中添加如下内容

    
            public boolean interceptScheme(WebView view, String url){
                try {
                    if(url.startsWith("tel:")) {
                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                        startActivity(intent);
                        return true;
                    }else if(url.startsWith("jiuxian:")) {
    
                        Uri uri = Uri.parse(url);
                        String query = uri.getQuery();
                        int paramIndex = query.indexOf('=');
                        String param = query.substring(paramIndex + 1);
                        if (param != null && param.startsWith(UrlFilter.URL_HOME)){
                            ActivityCenter.gotoHomeActivity(mContext, TabType.HOME);
                        }
                        return true;
                    }
                } catch (Exception e) {
                    return true;
                }
                return false;
            }
    
    

    11,webview右上角如果在非app 浏览器中打开显示 【立即下载】,如果在 本app webView 里打开则不显示【立即下载】按钮

    所有打开的web页面中默认都显示【立即下载】按钮,当从app webview中打开url时,会增加相应参数 比如 showQuickDownload = false,当页面收到该 参数时,把相应的 【立即下载】按钮隐藏掉

    代码如下:
    初始化和 shouldOverrideUrlLoading(WebView view, String url)
    方法中都得加

    private void handleUrl() {
            if (!TextUtils.isEmpty(mUrl)){
                Uri uri = Uri.parse(mUrl);
                uri = uri.buildUpon().appendQueryParameter(KEY_DEEPLINK, DEEPLINK_HIDE).appendQueryParameter(KEY_NET, BuildInfoHelper.getNetEnv()).build();
                if (!TextUtils.isEmpty(mUrl) && mUrl.contains(URL_MIAOSHA_WITH_TOKEN)) {
                    uri = uri.buildUpon().appendQueryParameter(SECKILLING_TOKEN, UserInfoManager.getUserToken()).build();
                }
                if (!TextUtils.isEmpty(mUrl) && mUrl.contains(DYNAMIC_PAGE_HIDE_KEY)) {
                    uri = uri.buildUpon().appendQueryParameter(DYNAMIC_PAGE_HIDE_FLAG, DYNAMIC_PAGE_HIDE_VALUE).build();
                }
                boolean noHandUrl = getIntent().getBooleanExtra("noHandUrl", false);
                if (!noHandUrl) {
                    uri = uri.buildUpon().appendQueryParameter(KEY_WEBP, WebViewUtil.getSupportWebpState()).build();
                }
                mUrl = uri.toString();
            }
        }
    
    

    12,什么鬼?妖怪吧? android webView 不支持加载的网页中有gif动态图片?

    根据自己多年的经验,android 的webView 就相当于PC端的浏览
    器,虽然4.4 之后采用 chrome 内核,但外在的表现形式应该一
    致,pc端的浏览器支持加载的网页中有gif动态图片,难道android
    系统的浏览器会不支持?经过思考后对前端的同学说:“默认
    android的浏览器是支持网页中有gif图片的”,事后android 7.2.2版
    本上线,8.3号那天运营同学在网页中配置了一个带gif的图片
    IOS 浏览器可以,android不行,当场打脸,郁闷的我开始了反
    思,,自己经过验证了吗?确实是这样的吗? 带着一些悔意和疑
    问,打开了百度和google。

    经过一顿操作,没有搜索到有用的信息,只能换种方式来实践了,
    于是我打开了手机系统自带的浏览器来加载这个带gif图片的连接,
    发现系统的浏览器(华为系统)也不支持,这是什么鬼?难到
    android的系统不支持加载带gif的图片?于是我又打开了UC浏览
    器,发现也不行,半信半疑的我又下载了chrome,搜狗浏览器,
    Firefox 发现只有Firefox 可以正常显示gif图片,(其它的浏览器只
    显示gif的第一帧),这又是什么鬼?难道各平台有兼容性?调侃的
    同时,我用mac上的chrome浏览器和safari也打开了该链接,发现
    mac上safari也支持加载带gif的图片(chrome不支持),这又是什
    么鬼,我日,这个时候我的心情是复杂的,再于我打开我们app的
    后门(测试环境下有个页面可以粘贴某个网址后打开这个链接的网
    页)打开了网上的某个[含有gif图片的网页]
    (https://www.gifjia5.com/53394/),发现这个连接是可以被我们的
    X5浏览器正常的加载并显示的,这说明什么呢?我的心情一下子就
    愉悦了说多。。。然后我用手机和电脑上的浏览器打开这个含有gif
    图片的网页
    ,于是我笑了,因为推
    理过后得出一个结论,应该是网页的问题 ,于是我找到相应的
    前端同学描述了该问题,他说这块确实是有相应的判断,判断条件
    是如果该浏览器支持webP就显示webP图片,否则显示gif图片,,
    也就是说safari和Firefox不支持webP格式的图片所以才正常显
    示gif图片。 而ios是不支持显示webP格式的图片的,所以显示gif
    显示
    ,前端改好后,android端测试ok,于是我笑了。

    参考

    理解WebKit和Chromium: WebKit, WebKit2, Chromium和Chrome介绍

    使用WebView显示GIF图

    火狐和IE,Safari不支持webp格式的图片

    解决webp格式兼容性问题

    浓缩的精华!从零开始带你认识最新的图片格式WebP

    Android端 WebP图片压缩与传输的一点探索

    webp格式 特点:

    优点:
    
    1 ,Google公司2010开发出来,压缩体积小 ,在质量相同的情况下,WebP格式图像的体积要比JPEG格式图像小40%,能节省大量的服务器宽带资源和数据空间
    
    缺点:
    
    1 .有损压缩
    
    2 .存在兼容性,并非所有浏览器都支持,火狐和ie,safari暂时还不支持webp格式,可以采用flash插件来显示webp,当然这样会耗费一些性能
    
    3 ,WebP格式图像的编码时间“比JPEG格式图像长8倍”。
    

    相关文章

      网友评论

          本文标题:WebView问题

          本文链接:https://www.haomeiwen.com/subject/bvpsrktx.html