1.http与https的区别

什么是HTTP?

互联网应用最广泛的网络协议
作用:浏览器和服务器之间传输文档

什么是HTTPS?

是以安全为目标的HTTP通道
安全版的的HTTP
HTTPS = HTTP + SSL层
作用:1建立信息安全通道,保证传输安全2确认网站的真实性

区别:

1 https需要到ca申请证书(免费证书少,需要一定费用)
2 信息传输方式不同:
http是超文本传输协议,信息明文传输
https具有安全性的SSL加密传输协议

3 默认端口不同:
http:80;https:443
(什么是默认端口:
是web服务默认的端口
比如我们访问http://www.baidu.com的时候
实际上是访问http://www.baidu.com:80 是一个标准,与浏览器无关,是服务器端的配置 )

4连接方式不同:
http:无状态的简单连接
https: 由http协议+SSL构建 可进行加密传输、身份认证的协议

2.变量提升与函数提升

变量提升

将 变量声明 提升到它所在作用域最开始的部分
a = 7; //初始化
console.log(a); //输出7
var a // 变量声明
*只提升变量声明,不会提升变量赋值

函数提升

将整个函数提升到最开始的部分
*只有函数声明才能够被提升,函数字面量不会进行函数提升

变量提升与函数提升的优先级:
函数提升 > 变量提升
且函数提升不会被变量声明覆盖,但是会被字面量赋值后覆盖

3.从输入url到页面呈现发生了什么?

整体流程

1.浏览器根据url查询ip
2.建立TCP连接
3.发送HTTP请求
4.服务器处理并返回http报文
5.浏览器解析渲染页面
6.关闭连接

浏览器根据url查询ip

DNS的定义:

域名系统(英文:Domain Name System,缩写:DNS)是互联网的一项服务。它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。DNS使用TCP和UDP端口53。当前,对于每一级域名长度的限制是63个字符,域名总长度则不能超过253个字符。
--维基百科

  • 1.浏览器查询自己的DNS缓存
  • 2.查询操作系统中的DNS缓存(存储在系统运行内存中的缓存)
  • 3.查询操作系统的hosts文件(存储在本地硬盘中的hosts文件)
  • 4.查询路由器缓存(部分路由器会将访问过的域名缓存)
  • 5.查询ISP DNS缓存(互联网服务提供商)
  • 6.操作系统将域名发送到本地域名服务器(LDNS)进行DNS解析:

DNS解析就是查询当前url需要的资源在哪台机器上的过程
DNS解析实现了url->ip地址的转换

DNS解析是一个递归查询的过程
ex:www.baidu.com.
逐级查询,首先在本地域名服务器查询ip地址 ,如果没有
-> 本地服务器向.根域名服务器发送请求 , 如果没有
-> 本地服务器向com顶级域名服务器发送请求 , 如果没有
-> 本地服务器向baidu.com域名服务器发送请求 ->获取ip返回本地域名服务器
网址的解析是从右到左的过程:.->com->baidu.com->www.baidu.com

ps:
理论上所有域名查询都必须先查询根域名
关于根域名查询:.com .net .cn等顶级域名由不同机构管理,通过询问根域名列表可以得知某顶级域名由谁托管,从而继续进行查询。
根域名列表很少变化,大多数DNS服务商都会提供缓存
参考文档

建立TCP连接

发送HTTP请求

构建HTTP请求报文并通过tcp协议发送到服务器指定端口

http请求报文 = 请求行 + 请求头 + 空行 + 请求主体

  • 请求行:
    = 请求方法 + 请求路径 + 协议版本 (method + request-url + http-version)
  • 请求头:
    一般以键值成对存在,包含了请求的附加信息(如声明浏览器语言,请求正文长度等)
  • 空行:
    协议中规定请求头和请求主体间必须用一个空行隔开
  • 请求主体:
    对于post请求,所需要的参数都不会放在url中,这时候就需要一个载体了,这个载体就是请求主题。

服务器处理请求并返回http报文

服务器指定端口收到请求后,根据url匹配到的路径做相应的处理,最后返回浏览器需要的资源。
浏览器会接收到一个响应报文,而所需要的资源就就在报文主体上。

响应报文 = 响应行 + 响应头 + 空行 + 响应主体

响应行:
同样包含了协议版本,同时包含的还有状态码状态码的原因短语

浏览器解析渲染页面

1.html代码解析-> dom tree
2.样式解析 -> style rules
3.dom tree + style rules = render tree
4.浏览器根据render tree 绘制页面

关闭连接

4.手撕柯里化&&

add(x,y) {
    return x + y;
}

function curry(fn) {
     var outerargs=Array.prototype.slice.call(arguments,1);
     var outerargs = [...arguments];
     return function(){
         var innerargs=Array.prototype.slice.call(arguments);
         var finalargs=outerargs.concat(innerargs);
         fn.apply(null,finalargs)
         console.log(fn.arguments);
     }
}

var cur1 = curry(add, 8);
console.log(cur1(6));   //14

5.跨域问题&&

什么是跨域?

浏览器的同源策略导致-> 不能执行其他网站的脚本 -> 产生跨域问题

同源策略

是浏览器对JavaScript施加的安全限制
同源是指, 域名, 协议, 端口相同。74

域名的组成

http:// www.baidu.com :9090 /dir/other.html ? xxxxx
协议 主机名 端口 文件路径 参数

跨域的方法

1.Jsonp

Jsonp是一种非正式传输协议
Jsonp = json + padding
利用<script>标签没有跨域限制的“漏洞” 来实现与第三方通讯
需要跨域时
在本站脚本中创建<script>元素,src指向跨域目标地址
同时提供一个回调函数来接收数据
跨域目标地址的响应应为用json包装的数据

2.document.domain

3.H5的postMessage

4.CORS跨域

未完

6.类数组转数组的方法

什么是类数组

1.拥有length属性
2.索引值为非负整数
3.不具有数组的方法(push,slice等)

转换方法

1.slice()

slice()不传参会返回一个原数组的拷贝,
(单层深拷贝,多层只深拷贝第一层)
slice不改变原数组

var arr = Array.prototype.slice.call(arguments);
//等价于
var arr = [].slice.call(arguments);

2.Array.from()

ES6的一种方法

var arr = Array.from(arguments);

3.扩展运算符...

var arr = [...arguments];

4.$makeArray

jQuery的一种方法

var arr = $makeArray(arguments);

5.原生js手写

新建数组循环存入

7.前端常见攻击方式及预防

XSS 跨站脚本攻击

原理

页面渲染的数据包含可执行的脚本,攻击者在Web页面中插入恶意script代码,当用户浏览时,恶意代码被执行,从而形成XSS攻击

常见攻击手段

//HTML节点内容注入
<div><script>alert(1);</script></div>  

//DOM属性注入
<img src='/images/1.png' onerror='alert(1);'>  

//javascript代码
<script>
    var a = '1';alert(1);''
</script>

//富文本是html标签,文字,以及样式的集合,很容易实现HTML节点内容注入和DOM属性注入,有被攻击的风险

防御手段

1.输入过滤
检测用户输入的内容,过滤 < > / 等可能导致脚本注入的字符 过滤script JavaScript等关键字,限制输入长度。同时要考虑用户绕开ASCIII码用十六进制编码进行脚本输入,因此对十六进制编码也要进行检测过滤
2.输出编码
当Web应用程序将用户的输入数据输出到目标页面中时,只要用HtmlEncoder等工具先对这些数据进行编码,然后再输出到目标页面中。这样,如果用户输入一些HTML的脚本,也会被当成普通的文字,而不会成为目标页面HTML代码的一部分得到执行。
3.Cookie防盗
利用XSS可以获取用户的cookie,所以要避免在cookie中泄露隐私,敏感信息可以将cookie利用MD5等hash算法进行多次散列后存放,同时将cookie和ip绑定,可以防止攻击者冒充用户身份

CSRF 跨站请求伪造

原理

在第三方网站向本站发起请求
用户在a网站前端进行登录请求->
a网站后端确认身份,用户登录成功,cookie中存有用户身份认证信息
b网站前端带着a站的身份信息向a网站后端发起登陆请求,请求成功
只要用户访问了b站的前端页面,b站就可以带着a站的用户登录态(cookie)向a站发起请求

防御手段

1.禁止第三方网站携带本站cookie: 设置same-site:strict (所有的第三方请求都不能携带本网站的cookie)
2.前端页面添加验证信息: 验证码 或 token验证
 验证码:当发起请求时,前端需要输入本网站页面的验证码信息,后端对验证码进行验证,验证码正确才会进行相关操作
 token验证:a站前端将token存在当前页面中(比如表单中的input隐藏域,meta标签或者任何一个dom的属性)和cookie中,当请求a站后端的时候,参数中带上这个token字段,a站后端将参数中的token和cookie中的token做对比, 相同则验证通过,不同则请求不合法

SQL注入

原理

将SQL命令插入到web表单提交输入域名、页面请求的查询字符串中,最终注入到后台数据库中,从而不按设计者的意图执行SQL语句,得到攻击者想要的数据(如账号密码)

防御手段

参数化查询已被视为最有效的可防御SQL注入攻击的防御方式。目前主流的ORM 框架都内置支持并且推荐使用这种方式进行持久层封装。

8.ZOOM属性

IE浏览器的专有属性
设置、检索对象的缩放比例

用于解决IE浏览器margin重叠、浮动清除、触发ie的haslayout(:true有自己的布局,false:继承父元素布局)

当设置了zoom的值之后,所设置的元素就会就会扩大或者缩小,高度宽度就会重新计算了,这里一旦改变zoom值时其实也会发生重新渲染,运用这个原理,也就解决了ie下子元素浮动时候父元素不随着自动扩大的问题。

如今用CSS3中的transform:scale实现其功能
参考链接

9.双飞翼布局、圣杯布局

概念

圣杯布局与双飞翼布局针对的都是三列左右栏固定中间栏边框自适应的网页布局

要求

三列布局,中间宽度自适应,两边定宽;
中间栏要在浏览器中优先展示渲染;
允许任意列的高度最高;

实现

构建html

    <body>
        <div class="container">
            <div class="main"> main </div>
            <div class="left"> left </div>
            <div class="right"> right </div>
        </div>

    </body>

设置基本样式

    .main, .left, .right {
        min-height: 130px;
    }
    .main {
        background: blue;
    }
    .left {
        background: green;
        width: 200px;
    }
    .right {
        background: red;
        width: 300px;

    }

效果图:

clipboard.png

2.设置container的padding

    .container {
        padding: 0 300px 0 200px;
    }

clipboard.png

3.三个子元素全部设置左浮动

    .main, .left, .right {
        min-height: 130px;
        float: left;
    }

clipboard.png

4.将主题main元素设置为100%宽度

    .main {
        background: blue;
        width: 100%;

clipboard.png

5. 设置左右负margin

    .left {
        background: green;
        width: 200px;
        margin-left: -100%;
    }
    .right {
        background: red;
        width: 300px;
        margin-left: -300px;

    }

clipboard.png

6.调整left和right的位置

    .left, .main, .right {
        position: relative
    }
    .left {
       left:-200px;
    }
    .right {
        right: -300px;
    }

clipboard.png

flex 实现

    <style>
        .container{
            display: flex;
            min-height: 130px;
        }     
        .main{
            flex-grow: 1;
            background-color: blue;
        }
        .left{
            order: -1;
            flex-basis: 200px;
            background-color: green;
        }
        .right{
            flex-basis: 300px;
            background-color: red;
        }

    </style>

    <body>
        <div class="container">
            <div class="main"> center </div>
            <div class="left"> left </div>
            <div class="right"> right </div>
        </div>

    </body>

10.<!DOCTYPE>

定义

document type ,用来说明所使用的html版本

作用

使浏览器获知文档类型
请始终向html文档中添加doctype声明

注意

<!DOCTYPE> 声明必须是 HTML 文档的第一行,位于 <html> 标签之前。
<!DOCTYPE> 声明不是 HTML 标签;它是指示 web 浏览器关于页面使用哪个 HTML 版本进行编写的指令。
<!DOCTYPE> 声明没有结束标签。
<!DOCTYPE> 声明对大小写不敏感。

用法

<!DOCTYPE html> 是h5标准,原先的是一串很长的字符串,现在是这个简洁形式,支持html5标准的主流浏览器都认识这个声明。

Doctype可声明三种DTD(document type definition)类型,分别表示严格版本、过渡版本以及基于框架的 HTML 文档。

在标准模式中,浏览器以其支持的最高标准呈现页面;
在混杂模式中,页面以一种比较宽松的向后兼容(兼容老的版本)的方式显示。混杂模式通常模拟老式浏览器的行为以防止老站点无法工作。
html5没有DTD,也就没有严格模式与宽松模式的区别,html5有相对宽松的语法,事实上,已经尽可能大的实现了向后兼容。

11.v-if和v-show的区别

v-if:

操作的是dom
切换开销大

v-show:

操作的是css
初始渲染开销大

什么时候用v-show?

频繁切换的场景下

什么时候用v-if?

操作组件时,有需求组件重新执行生命周期

12.如何判断一个object为空

1.通过JSON.stringfy()判断

if (JSON.stringify(data) === '{}') {
    return false // 为空,返回false
}
return true // 不为空,返回true

2.ES6的方法 Object.keys()

该方法会返回一个由给定对象的自身可枚举属性组成的数组。如果对象为空会返回一个空数组

var a = {}
Object.keys(a) // []

可根据数组长度判断true false

3. for...in遍历

for (var i in obj) { // 如果不为空返回true

return true

}
return false // 如果为空返回false

async/await

async/await是什么

async是异步的意思,用于申明一个function是异步的
await有等待的意思,用于等待一个异步方法执行完成

async语法

`//再函数开头加async关键字即可
async function f() {

return 1;

}
//async会返回一个promise 对象,如果function中返回的值会作为.then()的参数

f().then(res) {

console.log(res) //1

}
`

await语法

`
function testA() {

return 'hello!'

}

async function testB() {

return Promise.resolve('I am async');

}

async function testAB() {

const v1 = await testA();
const v2 = await testB();
console.log(v1, v2);

}

testAB(); //hello!I am async

`

await 只能在async函数中用

await操作符等的是一个返回的结果

如果是同步的情况,那就直接返回.

那如果是异步的情况,await会阻塞整个流程,直到结果返回之后,才会继续下面的代码。

async函数,会被包在一个promise中异步执行。
所以await只能在async函数中使用,如果在正常程序中使用,会造成整个程序阻塞,得不偿失。

错误处理

reject情况下的错误处理方案:

  1. try-catch捕捉错误

`
async function test() {

try {
    await Promise.reject(1);
} catch(err) {
    console.log(err);
}

}
test() //1
`

  1. promise的catch捕捉错误

`
async function test() {

await Promise.reject(1).catch(err) => {
    console.log(err);
}

}
test() //1
`

和promise的区别

promise最大的问题就是在于业务复杂之后,then内部的逻辑也变得复杂,或者循环的异步嵌套场景等,会写出来不那么优美
复杂逻辑中,async/await比then链有优势

问题池

VUE 为什么在列表组件中写key, 作用是?

for of for in 的区别

apply
reduce
bfc
三握四挥
垂直居中

typeof & instanceof


李默
24 声望2 粉丝

« 上一篇
前端笔记