JS-混淆&遗忘&难点

记录一些我经常混淆和遗忘的JS点


1. Date类型之时间格式化

1)toGMLString()、toUTCString()、toLocalString()、toString()

  • toGMLString()toUTCString() 都是表示国际标准时间,toGMLString() 已经被淘汰,建议使用 toUTCString()

  • toLocalString() 表示当地的时间

  • toString() 表示根据当地的时间,但是格式是国际上的格式

2. slice、subStr、substring

这三者都表示字符串切割("断章取义") [ slice方法Array对象也可以使用 ]

1)区别1:

  • slicesubstring 的第一个参数表示起分割index,第二个参数表示结束分割index,(不包括结束index)

  • substr 的第一个参数同上,第二个参数是表示要分割的个数

2)区别2:

  • 仅有 substring 会根据选择两个参数中较小的那个作为起始点

3)区别3:

参数中遇上负数

  • substring 中遇到负数直接视为0

  • substr 中遇到负数,第一个参数是字符串长度加上负数,第二个参数视为0

  • slice 中遇到负数,两个参数都是字符串长度加上负数

3. XSS和CSRF

  • XSS: 跨站脚本攻击(Cross Site Scripting),恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。

  • XSS

  • CSRF: 跨站请求伪造(Cross-site request forgery)通常缩写为CSRF或XSRF,是一种对网站的恶意利用。XSS 利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。

  • CSRF

4. sessionStorage、localStorage、session、cookie

  • localStoragesessionStoragecookie 都是用户存储客户端临时信息的对象,且同源的。

  • session 是存储在服务器的临时会话数据

  • localStorage 生命周期是永久

  • sessionStorage 生命周期为当前窗口或标签页

  • cookie生命周期取决于设置的cookie过期时间(如果没有设置过期时间,则浏览器关闭生命周期结束)

  • cookie 数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器来回传递。它还有路径的概念,可以限制cookie只属于某个路径下。cookie数据不能超过4k,因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据。

  • sessionStoragelocalStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。

  • Web Storage 实际上由两个部分组成:sessionStoragelocalStorage

点击这里

5. querySelector 和 getElementBy..区别 以及性能比较

点击这里

6. 获取不重复的随机数

    // 生成随机数
    getRandomNum(randomLength) {
      let rL = randomLength || 18;
      return Number(Math.random().toString().substr(3,rL) + Date.now()).toString(36);
    },

7. 判断浏览器是否是PC

// 判断是否是pc
isPc: function(req, res){
    let sUserAgent = req.headers["user-agent"].toLowerCase();
    let bIsIpad = sUserAgent.match(/ipad/i) == "ipad";
    let bIsIphoneOs = sUserAgent.match(/iphone os/i) == "iphone os";
    let bIsMidp = sUserAgent.match(/midp/i) == "midp";
    let bIsUc7 = sUserAgent.match(/rv:1.2.3.4/i) == "rv:1.2.3.4";
    let bIsUc = sUserAgent.match(/ucweb/i) == "ucweb";
    let bIsAndroid = sUserAgent.match(/android/i) == "android";
    let bIsCE = sUserAgent.match(/windows ce/i) == "windows ce";
    let bIsWM = sUserAgent.match(/windows mobile/i) == "windows mobile";
    let bIsWP = sUserAgent.match(/windows phone/i) == "windows phone";
    if (bIsIpad || bIsIphoneOs || bIsMidp || bIsUc7 || bIsUc || bIsAndroid || bIsCE || bIsWM || bIsWP) {
        return false;  //Mobile
    } else {
        return true;   //pc 
    }
},

8.上报错误到后台

  • window.onerror
  • addEventListener('error')
  • pormise用catch

doc

JS难点

1. 页面之间的通信

  1. url带参数 -- 单向传递

  2. 可以使用iframe进行嵌套

    1. 方法调用

      • 父页面调用子页面方法:FrameName.window.方法;
      • 子页面调用父页面方法:parent.window.方法;
      • 子页面获取父页面属性:parent.属性
      • 父页面获取子页面属性:Frame.contentWindow.属性

      vue中父页面的方法需要写到index.html或者定义window.parent/window.top = 方法

    2. 自定义事件的监听与调用

  3. postMessage -- 单向传递

    postMessage API

    注意: IE8 和 IE9 仅支持窗口与<frame><iframe> 之间的通信

  4. localStorage

  5. websocket

2. 数组中两个交换位置

  1. 方法一

    es6中引入扩展运算符(...),它用于把一个数组转化为用逗号分隔的参数序列,它常用在不定参数个数时的函数调用,数组合并等情形

        arr = [1, 2, 3, 4, 5]
        // 交换第三个和第四个元素
        // x < y
        x = 2, y = 3
        
        arr.splice(x, 1, ...arr.splice(y, 1, arr[x]))
        console.log(arr) /// [1,2,4,3,5]
    
  2. 方法二

        let a=[1,2,3];
        [a[1], a[2]]=[a[2], a[1]];
    

3. https中的iframe不能加载http的,会出现跨域问题

doc

4. 导出文件(后台传输回流的格式)

DOC

导出excel文件,请求头的accety格式为application/vnd.ms-excel

1.blob格式

new blob可以转化为blob格式

blob doc

<!--if (window.navigator.msSaveOrOpenBlob) // IE10+-->
<!--window.navigator.msSaveOrOpenBlob(file, filename);-->

let link = document.createElement('a');
let year = this.descData.year ? this.descData.year : '- -';
let month = this.descData.month ? this.descData.month : '- -';
link.style.display = 'none';
link.href = window.URL.createObjectURL(response.data);
link.download = `汇报明细_${year}年${month}月`;
document.body.appendChild(link);
link.click();
window.URL.revokeObjectURL(link.href);
document.body.removeChild(link);

2.如果是base64格式

  1. 加类型说明可直接下载

可以直接把base64加到a标签的link属性中在前面加上data:文件类型;base64,,download属性设置文件名字,可以下载

  1. 转化为file格式,在转换为blob格式,用1去下载
base64ToFile(base64Data, tempfilename, contentType) {
    contentType = contentType || '';
    var sliceSize = 1024;
    var byteCharacters = atob(base64Data);
    var bytesLength = byteCharacters.length;
    var slicesCount = Math.ceil(bytesLength / sliceSize);
    var byteArrays = new Array(slicesCount);

    for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
        var begin = sliceIndex * sliceSize;
        var end = Math.min(begin + sliceSize, bytesLength);

        var bytes = new Array(end - begin);
        for (var offset = begin, i = 0 ; offset < end; ++i, ++offset) {
            bytes[i] = byteCharacters[offset].charCodeAt(0);
        }
        byteArrays[sliceIndex] = new Uint8Array(bytes);
    }
    var file = new File(byteArrays, tempfilename, { type: contentType });
    return file;
}

download属性的兼容性较差,不建议使用,建议后台直接返回url去下载

download兼容一览

5. split方法分割多个字符

str.split(/[字符集合]/)

eg:
'aa-bb_cc/dd' -> [aa, bb, cc ,dd]
'aa-bb_cc/dd'.split(/[-_/]/)

6. base64 和 binary转化

btoa()/atob

ps: a -> ascii, b -> binary

7. onbeforeunload 事件在即将离开当前页面(刷新或关闭)时触发。

该事件可用于弹出对话框,提示用户是继续浏览页面还是离开当前页面。

兼容性好

8. 移动端阻止页面下拉事件

addEventListener

document.body.addEventListener('touchmove', function (e) {
    e.preventDefault(); //阻止默认的处理方式(阻止下拉滑动的效果)
}, {passive: false}); //passive 参数不能省略,用来兼容ios和android

9. 拿到其他页面的内容(仅浏览内容)

仅适用不考虑样式或内联样式的页面【例如:微信公众号文章】
【PS: 如果带有多图,必须要有浏览行为才可以拿到图片!!】
【所有跨域问题的解决必须有服务器权限和服务器配合 】

  1. 使用iframe做隐形的桥梁(拖慢页面渲染) -- 跨域不可取,浏览器安全限制
    将链接内容放到iframe中,获取iframe中的innerHTML拷贝出来。具体方法如下
    格式:
window.frames["iframe的name值"].document.getElementById("iframe中控件的ID").click(); 
实例:window.frames["ifm"].document.getElementById("btnOk").click(); 
 
格式: 
var obj=document.getElementById("iframe的name").contentWindow; 
var ifmObj=obj.document.getElementById("iframe中控件的ID"); 
ifmObj.click(); 
实例: 
var obj=document.getElementById("ifm").contentWindow; 
var ifmObj=obj.document.getElementById("btnOk"); 
ifmObj.click(); 
  1. 考虑使用node抓取数据(后台爬虫)

  2. JQ的load()方法 -- 跨域不可取,浏览器安全限制

  3. 直接请求页面,将拿到的结果回填 -- 跨域不可取,浏览器安全限制
    (ajax,fetch等)

  4. 使用代理转发一层(还未测试)-- 多图不可行,必须模拟浏览器行为

📌8. async await,promise,setTimeout执行顺序!!

9.解决浏览器保存密码自动填充问题

场景:注册/修改密码时含有type=password的input和在他之前非type=password的input时会自动填充浏览器保存的密码

  1. form表单可以隔断填充密码问题
<form>
 <input type="text" />
</form>
<form>
 <input type="password" />
</form>
  1. 用隐藏input隔开在chorme无效

  2. 通过focus修改type只在密码在上/除密码之外的input框在下的情况

10.formData

自行创建一个formData格式的请求用于上传文件

创建formData对象

const formData = new FormData();
formData.append('file', (某input元素对象).files[0]);
  • !!不能设置headers的contentType,因为设置Content-Type:multipart/form-data;后不会自动加boundary及之后的内容(例如Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryBHCQAyJZJXeOYet1
  • 注意body中的内容不需要JSON.stringify

js兼容

Response.redirected

一个Boolean是true如果响应表示您的请求被重定向。

ie监听storage差异与其他浏览器

storage变化,ie会刷新所有页面(与当前storage相关的)其他浏览器值会刷新当前页。可以通过比较newValue和oldValue再做出相应的操作

ie和safari不支持

ie get请求缓存不更新

// 兼容IE处理(IE缓存坑)
if (newConf.method.toLowerCase() === 'get') {
    newConf.params = Object.assign({}, (newConf.params || {}), {          _: new Date().getTime()
    });
}

js其他

input file读取文件

  1. 获取file对象: (元素).files[0]
  2. FileReader
  3. 获取url对象-通过file创建链接: createObjectURL

JS冷门知识点

js函数的6个基本术语

  • 匿名函数
  • 头等函数
  • 高阶函数
  • 一元函数
  • 柯里化
  • 纯函数

doc

实用api

  • 监听屏幕旋转变化接口: orientationchange
  • 电池状态:navigator.getBattery()
  • 让你的手机震动: window.navigator.vibrate(200)
  • 当前语言:navigator.language
  • 联网状态:navigator.onLine
  • 页面可编辑:contentEditable

doc

chorme插件

以上内容,如有错误请指出,不甚感激。
如需转载,请注明出处

posted @ 2019-05-23 16:28  FIONA-SUN  阅读(620)  评论(0编辑  收藏  举报