每日3+3前端面试题(2020.12.14)

HTML

在主框架下引入的iframe,检测这个iframe是否能打开,如果打不开则跳到404页面

我们知道 iframe 只有 onload 事件,没有 onerror 事件

非跨域

如果不跨域,那问题就很好解决了,有以下几种方案可以使用:

  1. 使用 ajax 发送一个 head 请求,看状态是否返回 200 (之所以发送 head 请求,是轻量级,响应速度快)。
  2. 检测 iframe 元素特征,在 iframe onload 触发后,检测 html 元素,例如有没有 title,内容是否为空等。

跨域

如果跨域的情况,要看你是否能控制跨域服务器。

兼容跨域/非跨域情况

  1. 使用定时器检测,如果onload触发时间晚于预设阈值,判定为无法加载。
  2. 使用link标签来测试url能否访问。

下面重点来讲下方案2。

link标签来测试url

我们为什么要使用link标签?

支持跨域的检测标签有如下几个:

  1. script
  2. img
  3. link
  4. video
  5. audio

支持 onload 和 onerror 的只有 script 、link、img

之所以不用 img、script的原因是:

  1. img会检测格式,如果不是图片类型,也会触发onerror。
  2. script可能会有安全问题(XSS等)。

能控制跨域服务器

可以使用 jsonp 或 CORS,允许客户端发送跨域 head 请求,来获取是否状态正常

如果不能跨域的情况,见下面的通用方案

<html>
	<body>
		<iframe id="iframe" onload="frameLoad()" width="100%" height="100%" src="https://baidu1.com">
		</iframe>
		<script>
			function frameLoad() {
				console.log('frame load')
			}

			function accessTest() {
				var link = document.createElement('link')
				link.rel = "stylesheet"
				link.type = "text/css"
				// 这里设置需要检测的url
				link.href = "https://baidu1.com"
				link.onload = function() {
					console.log('accessTest success')
				}
				link.onerror = function() {
					console.log('accessTest fail')
				}
				document.body.appendChild(link)
			}
			accessTest()
		</script>
	</body>
</html>

CSS

使用css如何拉伸字体

使用css3的front-stretch 但是很多游览器都不兼容

一般用display: inline-block;+ transform: scale();

display: inline-block;
transform: scale(5,3);
-ms-transform: scale(5,3);
-webkit-transform: scale(5,3);
-moz-transform: scale(5,3);
-o-transform: scale(5,3);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o13wH4G7-1607923473935)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20201214130415457.png)]

JavaScript

ES6的Proxy是什么,有什么应用场景

proxy基础

proxy做数据劫持用的和Object.defineProperty类似但是它的功能更强大,可以直接监听对象而非属性,也可监听数组

Vue

你知道v-model的原理吗?说说看

本质上一个语法糖,就是靠:bind="value"与@change="value = $event.target.value"的结合。

<input type="text" :value="msg" @input="msg=$event.target.value">
	{{msg}}
</input>

网络

讲一下 HTTP 与 HTTPS 的区别

http和https的主要区别是http是明文传输,http是传输的数据是加密过后的
http是80端口,https是443端口
http连接是无状态的,https是ssl+http构建的可加密传输,身份认证的网络协议,比http安全

https的缺点:

  • HTTPS协议握手阶段比较费时,会使页面的加载时间延长近50%,增加10%到20%的耗电;
  • HTTPS连接缓存不如HTTP高效,会增加数据开销和功耗,甚至已有的安全措施也会因此而受到影响;
  • SSL证书需要钱,功能越强大的证书费用越高,个人网站、小网站没有必要一般不会用。
  • SSL证书通常需要绑定IP,不能在同一IP上绑定多个域名,IPv4资源不可能支撑这个消耗。
  • HTTPS协议的加密范围也比较有限,在黑客攻击、拒绝服务攻击、服务器劫持等方面几乎起不到什么作用。最关键的,SSL证书的信用链体系并不安全,特别是在某些国家可以控制CA根证书的情况下,中间人攻击一样可行。

客户端在使用HTTPS方式与Web服务器通信时有以下几个步骤,

  • 客户使用https的URL访问Web服务器,要求与Web服务器建立SSL连接。

  • Web服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。

  • 客户端的浏览器与Web服务器开始协商SSL连接的安全等级,也就是信息加密的等级。

  • 客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。

  • Web服务器利用自己的私钥解密出会话密钥。

  • Web服务器利用会话密钥加密与客户端之间的通信。

NodeJS

如何使用nodejs对base64进行编解码?

基础补充
介绍:

先说buffer类

Buffer 类是一个全局变量,用于直接处理二进制数据。 它可以使用多种方式构建。

如:
const buf1 = Buffer.from('this is cxy');

console.log(buf1)					// <Buffer 74 68 69 73 20 69 73 20 63 78 79>   二进制显示的
console.log(buf1.toString())		// this is cxy
方法:
Buffer.alloc(size[, fill[, encoding]])

它的参数是:

  • sizeBuffer 的期望长度。
  • fill 用于预填充新 Buffer 的值。默认值: 0
  • encoding 如果 fill 是一个字符串,则这是它的字符编码。默认值: 'utf8'

分配一个大小为 size 字节的新 Buffer。 如果 fillundefined,则用零填充 Buffer

const buf = Buffer.alloc(5);
console.log(buf);
// 打印: <Buffer 00 00 00 00 00>


const buf = Buffer.alloc(5, 'a');
console.log(buf);
// 打印: <Buffer 61 61 61 61 61>

const buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64');
console.log(buf);
// 打印: <Buffer 68 65 6c 6c 6f 20 77 6f 72 6c 64>

注意:调用 Buffer.alloc() 可能比替代的 Buffer.allocUnsafe() 慢得多,但能确保新创建的 Buffer 实例的内容永远不会包含来自先前分配的敏感数据,包括可能尚未分配给 Buffer 的数据。

Buffer.allocUnsafe(size)

它的参数是:

  • size 新建的 Buffer 的长度。

以这种方式创建的 Buffer 实例的底层内存是未初始化的。 新创建的 Buffer 的内容是未知的,可能包含敏感数据。 使用 Buffer.alloc()可以创建以零初始化的 Buffer 实例。

const buf = Buffer.allocUnsafe(10);
console.log(buf);
// 打印(内容可能有所不同): <Buffer a0 8b 28 3f 01 00 00 00 50 32>

buf.fill(0);
console.log(buf);
// 打印: <Buffer 00 00 00 00 00 00 00 00 00 00>

注意:

Buffer 模块会预分配一个内部的大小为 Buffer.poolSizeBuffer 实例,作为快速分配的内存池,用于使用 Buffer.allocUnsafe() 创建新的 Buffer 实例、或 Buffer.from(array)、或 Buffer.concat()、或弃用的 new Buffer(size) 构造器但仅当 size 小于或等于 Buffer.poolSize >> 1Buffer.poolSize 除以二再向下取整)。

对这个预分配的内部内存池的使用是调用 Buffer.alloc(size, fill)Buffer.allocUnsafe(size).fill(fill) 两者之间的关键区别。 具体来说, Buffer.alloc(size, fill) 永远不会使用内部的 Buffer 池,而 Buffer.allocUnsafe(size).fill(fill)size 小于或等于 Buffer.poolSize 的一半时将会使用内部的 Buffer池。 该差异虽然很微妙,但当应用程序需要 Buffer.allocUnsafe() 提供的额外性能时,则非常重要。

Buffer.from(array)

已弃用:原api是 new Buffer(XXX)

参数:

  • array

使用 0255 范围内的字节数组 array 来分配一个新的 Buffer。 超出该范围的数组条目会被截断以适合它。

// 创建一个包含字符串 'buffer' 的 UTF-8 字节的新 Buffer。
const buf = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]);
Buffer.from(arrayBuffer[, byteOffset[, length]])
  • arrayBuffer一个 ArrayBufferSharedArrayBuffer,例如 TypedArray.buffer 属性。
  • byteOffset 开始拷贝的索引。默认值: 0
  • length拷贝的字节数。默认值: arrayBuffer.byteLength - byteOffset

创建 ArrayBuffer 的视图,但不会拷贝底层内存。 例如,当传入 TypedArray.buffer 属性的引用时,新建的 Buffer 会与 TypedArray共享同一内存。

const arr = new Uint16Array(2);

arr[0] = 5000;
arr[1] = 4000;

// 与 `arr` 共享内存。
const buf = Buffer.from(arr.buffer);

console.log(buf);
// 打印: <Buffer 88 13 a0 0f>

// 改变原先的 Uint16Array 也会改变 Buffer。
arr[1] = 6000;

console.log(buf);
// 打印: <Buffer 88 13 70 17>

可选的 byteOffsetlength 参数指定 arrayBuffer 中与 Buffer 共享的内存范围。

const ab = new ArrayBuffer(10);
const buf = Buffer.from(ab, 0, 2);

console.log(buf.length);
// 打印: 2
Buffer.from(string)
  • string 要编码的字符串。
  • encoding 的字符编码。默认值: 'utf8'

创建一个包含 string 的新 Bufferencoding 参数指定用于将 string 转换为字节的字符编码。

const buf1 = Buffer.from('this is a tést');
const buf2 = Buffer.from('7468697320697320612074c3a97374', 'hex'); 		// hex是16进制

console.log(buf1.toString());
// 打印: this is a tést
console.log(buf2.toString());
// 打印: this is a tést
console.log(buf1.toString('latin1'));
// 打印: this is a tést
Buffer.from(buffer)
  • buffer 要拷贝数据的 BufferUint8Array

拷贝 buffer 的数据到新建的 Buffer 实例。

const buf1 = Buffer.from('buffer');
const buf2 = Buffer.from(buf1);

buf1[0] = 0x61;

console.log(buf1.toString());
// 打印: auffer
console.log(buf2.toString());
// 打印: buffer
Buffer.from(object[, offsetOrEncoding[, length]])
  • object支持 Symbol.toPrimitivevalueOf() 的对象。
  • offsetOrEncoding 字节偏移量或字符编码。
  • length 长度。

对于 valueOf() 返回值不严格等于 object 的对象,返回 Buffer.from(object.valueOf(), offsetOrEncoding, length)

const buf = Buffer.from(new String('this is a test'));
// 打印: <Buffer 74 68 69 73 20 69 73 20 61 20 74 65 73 74>

对于支持 Symbol.toPrimitive 的对象,会返回 Buffer.from(object[Symbol.toPrimitive]('string'), offsetOrEncoding)

class Foo {
  [Symbol.toPrimitive]() {
    return 'this is a test';
  }
}

const buf = Buffer.from(new Foo(), 'utf8');
// 打印: <Buffer 74 68 69 73 20 69 73 20 61 20 74 65 73 74>

如果 object 没有提及的方法、或适用于 Buffer.from() 变量的其他类型,则抛出 TypeError

buf.toString([encoding[, start[, end]]])
  • encoding 使用的字符编码。默认值: 'utf8'
  • start 开始解码的字节偏移量。默认值: 0
  • end 结束解码的字节偏移量(不包含)。默认值: buf.length
  • 返回: String

根据 encoding 指定的字符编码将 buf 解码成字符串。 传入 startend 可以只解码 buf 的子集。

如果 encoding'utf8',并且输入中的字节序列不是有效的 UTF-8,则每个无效的字节都会由替换字符 U+FFFD 替换。

字符串的最大长度(以 UTF-16 为单位)可查看 buffer.constants.MAX_STRING_LENGTH

const buf1 = Buffer.allocUnsafe(26);

for (let i = 0; i < 26; i++) {
  // 97 是 'a' 的十进制 ASCII 值。
  buf1[i] = i + 97;
}

console.log(buf1.toString('utf8'));
// 打印: abcdefghijklmnopqrstuvwxyz
console.log(buf1.toString('utf8', 0, 5));
// 打印: abcde

const buf2 = Buffer.from('tést');

console.log(buf2.toString('hex'));
// 打印: 74c3a97374
console.log(buf2.toString('utf8', 0, 3));
// 打印: té
console.log(buf2.toString(undefined, 0, 3));
// 打印: té
编码和解码-题解:
字符串的base64互转
let baseStr =  Buffer.from("my name is cxy").toString('base64');
console.log(baseStr)
baseStr = Buffer.from(baseStr,'base64').toString()
console.log(baseStr)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-snzI2r7R-1607923473937)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20201214124419989.png)]

16进制和字符串互转
let baseStr =  Buffer.from("my name is cxy").toString('hex');
console.log(baseStr)
baseStr = Buffer.from(baseStr,'hex').toString()
console.log(baseStr)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GsqXEtfY-1607923473939)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20201214124704447.png)]

将本地图片文件流和base64互转
const fs = require('fs');
// 将本地图片转为base64
function base64_encode(file) {
    let bitmap = fs.readFileSync(file);
    return new Buffer(bitmap).toString('base64');
}
// 将base64转为本地图片
function base64_decode(base64str, file) {
    var bitmap = new Buffer(base64str, 'base64');
    fs.writeFileSync(file, bitmap);
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值