URLSearchParams 兼容性引发IOS 10 白屏问题

8 篇文章 0 订阅
1 篇文章 0 订阅

在使用公司平台提供的组件时,遇到在6s、7p时出现白屏情况,通过review代码发现平台的组件使用了URLSearchParams和es6 的includes。

通过caniuse.com 或者MDN查看 URLSearchParams兼容发现,对于低版本的IOS 10.3 ( 2017 年 3月发布)以下是不支持的。

使用URLSearchParams 实现URL拼接源码:

export function contactUrl (url = '', params = {}) {
  let qs = new URLSearchParams()

  for (let key in params) {
    qs.append(key, params[key])
  }

  if (url.includes('?')) {
    return url + '&' + qs.toString()
  } else {
    return url + '?' + qs.toString()
  }
}

如何解决?

1、使用url-search-params-polyfill 

2、自己使用字符串拼接URL

乍一看这实现很简单很好修改,直接使用字符串拼接方式:

对于简单的参数(字符串,数字)这样处理是没有问题的,如果传入的params 中存在特殊参数(加密串),这种简单处理就出现无法匹配的问题了。

项目中正好有个特殊参数加密session_id ,使用上面的实现出现无法通过校验的问题。对比2个方式的请求URL发现session_id长度不一致,尝试过多种方式都无效,最后参考url-search-params-polyfill 是如何实现的。

URLSearchParamsPolyfill源码分析

在url-search-params-polyfill的 index.js 中,我们看到append(name, value)的实现是调用appendTo() 将name, value 作为一个数组的key , value 存储在this身上。

直接看appendTo(dirct, name ,value) 方法(append 调用中dirct 指向 对象this):

  function appendTo(dict, name, value) {
        var val = typeof value === 'string' ? value : (
            value !== null && value !== undefined && typeof value.toString === 'function' ? value.toString() : JSON.stringify(value)
        );

        if (name in dict) {
            dict[name].push(val);
        } else {
            dict[name] = [val];
        }
    }

append 没有特殊,再来看下URLSearchParamsPolyfill中的toString方法:

   prototype.toString = function() {
        var dict = this[__URLSearchParams__], query = [], i, key, name, value;
        for (key in dict) {
            name = encode(key);
            for (i = 0, value = dict[key]; i < value.length; i++) {
                query.push(name + '=' + encode(value[i]));
            }
        }
        return query.join('&');
    };

遍历this对象每个元素,并对每个元素进行encode后拼接成参数字符('a=b&c=d')。

重点就在于对每个元素encode 方法,通过源码分析它的实现并不是简单进行encodeURIComponent , 同时进行了字符串进行编码escape。

    function encode(str) {
        var replace = {
            '!': '%21',
            "'": '%27',
            '(': '%28',
            ')': '%29',
            '~': '%7E',
            '%20': '+',
            '%00': '\x00'
        };
        return encodeURIComponent(str).replace(/[!'\(\)~]|%20|%00/g, function(match) {
            return replace[match];
        });
    }

看到这里就已经很明了,URLSearchParams在对象调用toString时对元素参数进行的处理。

最后在自我实现的方法拼接字符串的时候添加相应的字符编码处理,把问题解决了。

参考资料:

url-search-params-polyfill

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Sticky模式是一种在网页或应用程序中常见的效果,它可以使元素固定在页面的特定位置,无论滚动页面时该元素是否可见。然而,在iOS设备上,存在一些兼容问题需要注意。 第一个兼容问题是页面元素的容器是否支持sticky定位。在一些旧版本的iOS设备上,容器元素如果使用了transform属或position属为fixed时,sticky定位会失效。因此,在开发过程中,我们应尽量避免在容器元素上使用这些属,以确保sticky定位的正常运行。 第二个兼容问题是滚动容器的滚动方式。在某些iOS设备上,当滚动容器(例如overflow属设置为scroll或auto的元素)内部的内容过多时,sticky元素可能会出现跳动或抖动的问题。这是因为滚动容器的滚动方式与浏览器的渲染方式有关。为了避免这个问题,我们可以尝试将滚动容器的滚动方式设置为transform或will-change属。 第三个兼容问题是触摸事件处理。在一些iOS设备上,滚动容器内部的sticky元素可能无法正确响应触摸事件,导致无法正常交互。这个问题可能与iOS设备的触摸事件处理机制有关,但我们可以尝试通过修改CSS代码或使用JavaScript来处理这个问题。 总的来说,sticky兼容问题主要集中在iOS设备上。在开发过程中,我们需要注意容器元素的属、滚动容器的滚动方式以及触摸事件的处理,以确保sticky定位在iOS设备上的正常运行。如果遇到兼容问题,我们可以尝试使用其他定位方式或通过修改代码来解决。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值