字符串
常用的一些方法如下:
-
split()
-
indexOf()
-
slice()
-
sub()
-
substr()
-
toString()
具体这些方法的使用,可以参考上面数组中提供的那个网站上去参考
EventLoop:即事件循环,指浏览器或Node的一种解决js单线程不会阻塞的机制,其是一种执行模型,在不同的地方有不同的实现,浏览器和NodeJs都是基于不同的
技术实现了各自的EventLoop,可以概述为以下两点:
-
浏览器的EventLoop是在h5规范中所写
-
noeJs的EventLoop是基于libvue实现的
理解事件循环,首先需要区分两个任务
- 宏任务(macrotask),也叫tasks,一些异步执行的任务的回调会依次的进入macro task queue,等待后续被调用,这些任务包括
-
setTimeout
-
setInterval
-
setImmediate(node独有)
-
requestAnimation(浏览器独有)
-
I/O
-
UI rendering(浏览器独有)
- 微任务(microtasks),也叫jobs,这些异步任务包括
-
process.nextTick(node独有)
-
Promise.then()
-
object.observe()
-
MutationObserve(注意: promise构造函数里的代码是同步执行的)
上面的这些任务,只需要记住就行了
浏览器中事件循环的机制
在浏览器中,只有一个执行栈和一个任务队列,在任务队列中放的是宏任务浏览器中事件循环的执行方式为:每从事件队列中取出一个事件时,有微任务就把微任务执行完,然后才开始执行事件(即从任务队列中去拿一个宏任务)
举个栗子
console.log(1)
setTimeout(function(){
console.log(2);
},0)
new Promise(() => {
console.log(3);
setTimeout(() => {
console.log(4);
})
})
console.log(5);
具体的结果可以自己试试,然后结合在浏览器中的事件循环的执行方式来理解对于node中的事件循环机制,会涉及到六个队列,执行的方式也不一样,具体可以在网上看看博客
对于this指向只需要记住下面的几个点
-
函数预编译过程中指向的就是window对象。
-
全局作用域——>指向window
-
call/apply会改变函数运行的指向
-
obj.function(); function()里面的this指向的就是obj.谁调用了这个方法,this就指向谁。
上面的四点只需要记住就是了,这里就举一个例子说明下
var a = 5;
function test(){
a = 0;
console.log(a);
console.log(this.a);
var a;
console.log(a);
}
test();
new test();
上面这两种打印出的结果分别为 0 5 0 和 0 undefined 0;对于test()执行的这种方式,就是一个方法的调用,此时并没有某个对象去调用这个方法,因此此时this.a指的就是全局变量中的a,因此打印出的就是5。而在new test()就是新建一个对象的过程,在新建对象的过程中,this.a并没有指向的是window对象,也没有指明是当前的实例对象,因此在这里输出的就是undefined
对于数组的去重方式有很多种,这里列举了其中的一些方法,关于去重,自己可以想一下或者去实现自己所能够想到的数组去重的方式
- 利用Set数据结构进行去重
function unique(arr){
return Array.from(new Set(arr));
}
这种方法所实现的去重无法去掉空对象
- 使用双重for循环,然后使用splice去重
function unique(arr){
for(let i = 0; i < arr.length - 1; i++){
for(let j = i + 1; j < arr.length; j++){
if(arr[i] == arr[j]){
arr.splice(j, 1);
j–;
}
}
}
}
- 使用indexOf去重
function unique(arr){
if(! Array.isArray(arr)){
console.log(‘type error’);
return;
}
var array = [ ];
for(let i = 0; i < arr.length; i++){
if(array.indexOf(arr[i]) === -1){
array.push(arr[i]);
}
}
return array;
}
- 利用sort()
function unique(arr){
if(! Array.isArray(arr)){
console.log(‘type error’);
return;
}
arr = arr.sort(); //使用此方法的目的是为了将重复的内容放在一起
let array = [arr[0]];
for(let i = 1; i < arr.length; i++){
if(arr[i] !== arr[i - 1]){
array.push(arr[i]);
}
}
return array;
}
- 利用includes方法
function unique(arr){
if(! Array.isArray(arr)){
console.log(‘type error’);
return;
}
let array = [ ];
for(let i = 0; i < arr.length; i++){
if(!array.includes(arr[i])){
array.push(arr[i]);
}
}
return array;
}
- 利用hasOwnproperty
function unique(arr){
let obj = { };
return arr.filter(function(item, index, arr){
return obj.hasOwnProperty(typeof, item + item) ? false : (obj[typeof item + item] = true)
})
}
使用hasOwnProperty判断是否存在对象属性
- 利用filter
function unique(arr){
return arr.filter((item, index, arr) => {
return arr.indexOf(item, 0) === index;
})
}
这里就不全部举例完了,还有一些方式,可以自行参考一些博客
对于深度克隆与浅度克隆,无非就是对于对象的拷贝问题进行的一个探讨,对于基本类型的赋值就是值传递,对于特殊类型对象的赋值,是将对象地址的引用赋值,这时候修改对象中的属性或者值,会导致所有引用的这个对象的值得改变,如果想要真正的赋值一个新的对象,而不是复制对象的引用就会用到深拷贝
- 浅拷贝:
- 使用=符号
let str1 = {
a: 1,
b: 2,
c: 3,
d: {
e: 5
}
}
let str2 = str1;
str2.d.e = 4;
console.log(str1,str2)
对于这种形式的对象的拷贝,当更改掉str2中的内容后,会导致str1中的改变
- Object.assign()
该方法实际上是一个浅拷贝的过程,与=的区别在与Object.assign()可以处理一层深拷贝
- 深拷贝
-
使用JSON.parse(JSON.stringify(str))进行拷贝,但是该方法对于function不进行任何拷贝
-
使用for in进行深拷贝具体实现方式如下
function deepclone(target, origin){
var target = target || {},
toStr = Object.prototype.toString;
arrStr = ‘[object Array]’;
for(var item in origin){
if(origin.hasOwnProperty(item)){
if(origin[item] !== null && typeof(origin[item]) == ‘object’){
if(toStr.call(origin[item]) === arrStr){
target[item] = [];
}else{
target[item] = {};
}
deepclone(target[item],origin[item]);
}else{
target[item] = origin[item];
}
}
}
}
-
内存泄漏指得是任何对象在不再拥有或需要它之后缓存在的情况
-
垃圾回收机制,会定时扫描对象,并计算引用每个对象的其他对象的数量,如果一个对象的引用数量为0(即没有其他对象引用该对象),或该对象的唯一引用是循环的,那么该对象的内存即可回收
-
造成内存泄漏的几种情况
-
setTimeout中的第一个参数使用字符串而不是函数时
-
闭包
-
控制台日志
-
循环(两个对象彼此引用,并且彼此保留时,就会产生一个循环)
即通过多次的传参使得某个函数的参数达到饱和,具体实现思想如下
-
首先实现将函数的参数拆分为两个部分,即下面的FixedParame方法的实现
-
然后再采用递归的思想,将函数传入的参数进行多次划分,直到达到最大化
function FixedParame(fn){
var _args = [].slice.call(arguments, 1);
return function(){
var newArgs = _args.concat([].slice.call(arguments, 0));
return fn.apply(this, newArgs);
}
}
function newCurry(fn, length){
var length = length || fn.length;
return function(){
if(arguments.length < length){
var cobined = [fn].concat([].slice.call(arguments, 0));
return newCurry(FixedParame.apply(this, cobined),length - arguments.length);
}else{
return fn.apply(this, arguments);
}
}
}
其目的就是将几个函数的功能给组合在一起,下面封装一个组合函数,在使用函数时,只需要将函数传入即可
function compose(){
//将类数组转化为数组,这样才能使用数组方法
var args = Array.prototype.slice.call(arguments);
var len = args.length - 1;
return function(x){
var result = argslen;
while(len–){
result = argslen;
}
return result;
}
}
- 节流
对于节流要明白两个点:
-
节流的目的是为了防止网站遭到恶意的攻击
-
节流函数的封装过程
下面就是封装的一个节流函数
function throttle(handler, wait){
var initTime = 0;
return function (e){
var nowTime = new Date().getTime();
if(nowTime - initTime > wait){
handler.apply(this, arguments);
initTime = nowTime;
}
}
}
- 抖动
对于抖动函数明白两点:
-
抖动函数的目的函数在频繁发生时,在等待一段时间后去执行的行为
-
抖动函数的封装过程
下面就是抖动函数的封装实现
function debounce(handler, delay){
var timer = null;
return function(){
var _self = this, _args = arguments;
clearTimeout(timer);
timer = setTimeout(function(){
handler.apply(_self, _args);
},delay);
}
}
函数的扁平化,其目的其实就是将一个多维数组变为一个一维数组的过程。在Array中有一个flat(),其作用就是如此,接下来就手动实现falt()函数
function flatten(){
var arr = arr || [];
var toStr = Object.prototype.toString;
this.forEach(item => {
return toStr.call(item) == ‘[object Array]’ ? arr = arr.concat(item.flatten()): arr.push(item);
})
}
对于了解事件冒泡和事件捕获,其实就是事件流的一个接收事件顺序,而事件流描述的就是从页面中去接收事件的顺序
事件流分为三类:
-
事件冒泡流:从内到外进行事件的捕获 (IE事件流)
-
事件捕获流:从外到内进行事件的捕获(NetScape事件流)
-
DOM事件流:事件捕获阶段——目标——事件冒泡阶段
对于这里需要去加一个问题进行讨论,也是在面试中可能被问道的问题
IE和DOM事件流之间的区别:
-
执行顺序不一样
-
事件参数和this指向不一样
-
事件加不加on
是一种用于创建快速动态网页的技术,通过在后台与服务器进行少量数据交换,ajax可以使网页实现异步更新,可以在不重新加载整个页面的情况下,对页面的某个部分进行更新。
以下的部分是ajax原理实现过程
- XMLHttpRequest对象
当前现代浏览器中均支持XMLHttpRequest对象(IE5和IE6使用ActiveXObject),因此为了应对所有的浏览器,包括(IE5和IE6),则在创建xmlhttp时,需要通过下面的这种方式来创建
var xmlHttp;
if(window.XMLHttpRequest){
xmlHttp = new XMLHttpRequest();
}else{
xmlHttp = new ActiveXObject(“Microsoft.XMlHTTP”);
}
当创建好xmlHttp之后,如果需要将请求放到服务器,需要使用XMLHttpRequest对象的open()和send()方法
对于get和post方法,在使用时的情况是不一样的,大多数的情况下都可以使用get请求,但是在下面的情况中使用post请求
-
无法使用缓存文件(更新服务器上的文件或数据库中的文件时)
-
向服务器发送大量数据(post没有数据量的限制)
-
发送包含未知字符的用户输入时,post比get更稳定也更加的可靠
如果需要通过GET方法发送信息,并且向URl添加信息:
xmlhttp.open(“GET”,“demo_get2.asp?fname=Bill&lname=Gates”,true);
xmlhttp.send();
如果需要通过POST那样传送数据,还需要对传入的数据做设置,因此会设置请求头,如下所示:
setRequestHeader()来添加HTTP头
xmlhttp.open(“POST”,“ajax_test.asp”,true);
xmlhttp.setRequestHeader(“Content-type”,“application/x-www-form-urlencoded”);
xmlhttp.send(“fname=Bill&lname=Gates”);
- 说到这里需要停顿以下,这里GET和POST请求是什么呢?
这个是应用层中http请求中的两种前后台数据交互的一种方式,在现如今的都是采用这种数据交互方式来实现前后端的交互,这样做的目的是为了前后端的分离,这样做的好处很多如上面所说的加载数据时,只需要更新一部分的内容即可,另外在开发时间上只要前后端做好数据规范,能做到前后端同时进行开发,大大减少开发项目的周期,另外在项目的可维护性上也有很大程度上的帮助等。在这里所涉及到的http协议部分,也是我们前端所需要了解的部分,这部分会在下面的网络部分进行讲解
- 上面的部分是将前端的数据发送给服务器,那么对于服务器返回的数据应该怎样处理呢?
这时就要用到onreadystatechange事件,当请求被发送到服务器时,需要执行一些基于响应的任务,每当readtState改变时,就会触发onreadystatechange事件。readyState属性存在XMLHttpRequest的状态信息。因此在这里就有关于XMLHttpRequest对象的属性
| 属性 | 描述 |
| — | :-: |
| onreadystatechange | 存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。 |
| readyState | 存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。0:请求未初始化1: 服务器连接已建立2: 请求已接收3: 请求处理中 4: 请求已完成,且响应已就绪 |
| status | 200: “OK”,404: 未找到页面 |
当服务器响应已经做好被处理的准备时,即就有以下的部分
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
document.getElementById(“myDiv”).innerHTML=xmlhttp.responseText;
}
}
在上面的代码中if部分就是表示服务器已经准备好了的描述过程,document.getElementById(“myDiv”).innerHTML=xmlhttp.responseText;中的responseText
表示服务器返回给前端的数据。上面的所有部分就是ajax整个原理的过程,在jq中也有封装好的ajax技术参考https://www.w3school.com.cn/jquery/jquery_ajax_get_post.asp,又或者在react或者是vue中(其依赖包axios,在npm官网上可以查看其用法)
- 原型链继承
function Person(name, age){
this.name = name;
this.age = age;
}
function Student(school){
this.school = school;
}
Student.prototype = new Person();
const student = new Student();
原型链继承缺点:多个实例对引用类型的操作会被篡改
- 构造函数继承
function Car(name, color, size){
this.name = name;
this.color = color;
this.size = size;
}
function Baoma(name, color, size, model){
Car.call(this, name, color, size);
this.model = model;
}
利用call方法,来实现继承
缺点:
-
只能继承父类的实例属性和方法,不能继承原型属性/方法
-
无法实现复用,每个子类都有父类实例函数的副本,影响性能
- 组合函数继承
用原型链实现对原型属性和方法的继承,用构造函数来实现实例属性的继承
function Animal(type, size, food){
this.type = type;
this.size = size;
this.food = food;
}
Animal.prototype.sayName = funciton(){
console.log(this.name);
}
function Dog(type, size, food, age){
Animal.call(this, type, size, food);
this.age = age;
}
Dog.prototype = new Animal();
缺点:在使用子类创建实例对象时,其原型中会存在两份相同的属性/方法
- 原型式继承
利用一个空对象作为中介,将某个对象直接复制给空对象构造函数的原型
function object(obj){
function F(){};
F.prototype = obj;
return new F();
}
即object()对传入其中的对象执行了一次浅复制,将构造函数F的原型直接指向传入的对象。
缺点:
-
原型链继承多个实例的引用类型属性指向相同,存在篡改的可能
-
无法传递参数
- 圣杯模式继承(寄生组合式继承)
这样实现的方式好处在于,当改变继承对象的属性时,并不会更改父类的原型
var inherit = (function(){
var F = function(){};
return function(Target, Origin){
F.prototype = Origin.prototype;
Target.prototype = new F();
Target.prototype.constructor = Target;
Target.prototype.uper = Origin.prototype;
}
})()
也可以使用下面的方式来实现,,借用构造函数传递参数和寄生模式实现继承
function inheritPrototype(target, origin){
var prototype = Object.create(origin.prototype);
prototype.constructor = target;
target.prototype = prototype;
}
- 使用es6中的extends
对于图片的懒加载和预加载可参考博客https://juejin.im/post/5b0c3b53f265da09253cbed0
- 懒加载:也叫延迟加载,指的是在长网页中延迟加载图想,是一种很好优化网页性能的方式
优点:
-
能提升用户的体验
-
减少无效资源的加载
-
方式并发加载的资源过多会阻塞js的加载
- 预加载:将所有所需资源提前请求加载到本地,之后再取用时,就直接从缓存中拿资源,具体原理以及实现方式参照上述博客
======================================================================
cookie、sessionStorage和localstorage之间的区别
-
sessionStorage: 在sessionStorage中的数据,只能在同一个会话页面才能访问,并且当会话结束后数据也会随之销毁,因此其是一个会话级别的存储。
-
localStorage: 用于持久化的本地存储,除非主动删除数据,否则数据用于不会过期
-
cookie: cookie的作用是与服务器进行交互,作为http规范的一部分而存在,记录客户端的用户信息,其大小限制在4KB左右
-
sessionStorage和localStorage的大小大概为5M左右
对于缓存其存在的意义在于可以加快相应事件,提高用户的体验,对于一般的html文件,浏览器会自动访问,对于ajax请求所发送的数据,有时也需要缓存,需要注意的是post请求浏览器是不会进行缓存的。
- http状态码304
该状态码代表的意思是服务器不会给我们数据,因此当前浏览器中有缓存的数据,此状态码代表使用缓存,当浏览器看到此状态码就应该去拿缓存中的数据
- 浏览器中缓存方式
- 协商缓存:根据前后台状态来判定是否要进行缓存
ETags和If-None-Match
- ETags是响应头中的内容,If-None-Match是请求头中内容,首次请求结束后会将ETags设置在If-None-Match中,第二次请求时,则会将ETags传输到服务器中
对比ETags如果相同(表示两次请求的内容相同),则服务器会返回304状态码,这时浏览器应该取缓存中的数据
last-Modified和If-Modified-since
-
last-Modified是响应头中的内容,If-Modified-since是请求头中的内容,其发生的过程与上面的类似,如果对比两次结果相同,这时服务器就会返回304状态码
-
强制缓存:强制设定缓存数据的存储时间,一到时间就清空缓存数据
-
Cache-control: 请求头部和响应头部都可以包含该字段,此字段是用来设置浏览器缓存的保留时间,可设置为以下值:
-
no-Cache: 不缓存
-
no-Store: 用于防止重要的信息被无意的发布
-
max-age: 指示客户机可以接收生存期不大于指定时间的响应
-
min-fresh:指示客户机可接收响应时间小于当前时间加上指定时间的响应
-
max-stale: 指示客户机可以接收超出超时间的响应时间
-
Expires: 内容保质器,若其和max-age同在则会被覆盖掉,其参数值设定时,可直接设置时间
-
浏览器内核主要有以下部分组成
-
渲染引擎
-
js引擎
-
执行栈
-
事件触发线程
-
消息队列
-
网络异步线程
-
定时器线程
=====================================================================
http协议规定了浏览器怎样向万维网服务器请求万维网文档,以及服务器怎样把文档传送给浏览器,从层次角度看,其是面向事务的应用层协议,是万维网上能够可靠地传递文件(文本、声音、图像等各种多媒体文件)的重要基础。其协议本身是无连接的,但是其使用了面向连接的TCP作为运输层协议,保证了数据的可靠性传输。
因此http协议在发送请求时,首先需要和服务器建立TCP连接,当建立TCP连接的三报文握手的前两部分完成后,万维网客户就把请求报文,作为TCP连接的三报文握手
中的第三个数据发送给万维网服务器,服务器收到HTTP请求报文后,就把所有请求的文档作为响应报文返回客户。因此整个网络的请求过程可以描述为以下内容:
-
网络请求的过程:
-
浏览器通过DNS域名解析到服务IP
-
客户端(浏览器)通过TCP协议建立到服务器的TCP连接(三次握手)
-
客户端(浏览器)向web服务器端(HTTP服务器)发送HTTP协议包,请求服务器里的资源文档 (telnet模拟)
-
服务器向客户端发送HTTP协议应答包
-
客户端和服务器断开(四次挥手),客户端开始解释处理HTML文档
-
对于get请求与post请求的常规理解
-
GET使用URL或Cookie传参,而POST将数据,放在BODY中。
在GET请求中它的参数是要拼接到URl后面的,POST请求它的请求data是拼接在请求主体中
- GET的URL会有长度上的限制,POST可以传输很多数据。
GET在长度上有限制是因为请求的data放在URL后面,URL的输入框是有限制的
POST传输的数据也会有一定的限度,因为这是为了安全性的考虑,为了防止恶意攻击
- POST比GET安全。
POST请求中的数据是可见的,不要将用户名等私密信息放在POST请求中
http请求中请求报文与响应报文的内容
- http(请求报文,响应报文)通过报文进行沟通
请求报文:
请求头 请求行 请求主体
请求头: 在请求头中的内容包括 1. 请求方式 2.请求url 3. http协议及版本
- 相应报文
响应头 响应行 响应主体
- 1.0和1.1之间的区别
-
缓存处理,在HTTP1.0中主要使用header里面If-Modified-Since,Expires来作为缓存判断的标准。HTTP1.1则引入了更多的缓存控制等策略,例如:Enity tag, If -unmodifiedSince,If-Match等更多可供选择的缓存头来控制缓存策略
-
带宽优化及网络连接使用
-
错误通知管理,在1.1中新增了324个错误状态码
-
Host头处理,1.1中认为每台服务器都绑定了一个唯一的ip地址,在请求消息中的URL并没有传递主机名,但随着虚拟主机技术的发展,一台物理服务器上可存在多供虚拟主机,并且共享一个ip地址,
HTTP1.1的请求消息和响应消息都支持Host头域,且如果请求消息中没有Host头域会有(400的错误码)
- 长连接,1.1协议的持续连接方式有两种,即是一个在TCP连接上可以传送多个请求和响应,在1.1种默认是打开了connection: keep-alive,一定程度上弥补了1.0每次都要创建连接的特点
- https和http之间的一些差别
-
https是需要到CA申请证书,需要进行交费,费用很少
-
http运行在tcp上,所有传输的内容都是明文,https运行在SSL/TLS之上,SSL/TLS运行在TCP之上,所有的传输内容都经过加密
-
HTTP和HTTPS使用的是完全不同的连接方式,HTTP默认端口80 HTTPS默认端口443
-
HTTPS可以有效的防止运营商劫持,解决了防劫持的一个大问题(防劫持:在使用webApp,流量里既有通信数据又有程序代码与界面)
- SPDY:HTTP1.x的优化
SPDY方案优化了HTTP1.x的请求延迟,解决的了HTTP1.x的安全性
-
降低延迟,针对HTTP高延迟问题,SPDY采取了多路复用的方式,多路复用通过请求stream共享一个tcp连接方式,解决HOL Blocking的问题,降低了延迟的同时提高了带宽的利用率
-
请求优先级。由于多路复用带来的共享连接时。关键请求可能会导致请求被阻塞。SPDY允许给每个request设置优先级,这样重要的请求就会优先得到响应
-
header压缩,HTTP1.x的header很多时候都是重复多余的,选择合适的压缩算法可以减小包的大小和数量
-
基于HTTPS的加密协议传输
-
服务器端推送,服务端可将文件推送给客户端,下次访问文件可以从缓存中获取。
- HTTP2.0和SPDY方案之间的差异
-
HTTP2.0支持明文传输,而SPDY强制使用HTTPS
-
HTTP2.0消息头的压缩算法采用HPACk,而非SPDY采用的DEFLATE
- HTTP2.0和HTTP1.x相比的新特性
-
新的二进制格式
-
多路复用
-
header压缩
-
服务器端推送
- HTTP2.0的升级改造
-
HTTP2.0可以支持非HTTPS的。当当今主流的浏览器像chrom,firefox表示还是支持基于TLS部署的HTTP2.0协议所以想要升级为2.0,先升级https协议为好
-
当网络升级为https之后,升级2.0只要在nginx对应的配置文件中启动相应的协议就行
-
当网络升级为2.0之后,不用担心其不支持http1.x因为,2.0满足向下兼容的语义,对于不支持2.0的浏览器,NGINX会自动向下兼容
- 2.0中的多路复用与1.x中的长连接复用之间的区别
-
1.*:一次请求一次响应,建立一个连接,用完关闭;每个请求都要建立一个连接
-
1.1:pipeling解决方案,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某个请求超时等,后续请求只能被阻塞,毫无办法,也就是常说的线头阻塞
-
2.0多个请求同时在一个连接上并行执行时,某个请求任务耗时严重,不会影响到其他连接的正常执行
- 为什么需要头部压缩(header压缩)?
假定一个页面100供资源需要加载,而每次请求都有1kb的消息头,则至少需要消耗100kb来获取消息头,2.0可以维护一个字典,差量更新http头部,大大降低因为头部传输而产生的流量
- 2.0中多路复用的好处?
http性能优化的关键并不在于高带宽而是低延迟。TCP连接会随着时间进行自我“调谐”,起初会限制连接的最大速度,如果数据成功传输,会隋卓时间的推移,提高传输的速度,在这种调谐则被称为TCP慢启动。由于这种原因,让原本具有突发性和短时性的HTTP连接变得十分低效。2.0通过让所有数据流共用同一个连接,可以有效的使用TCP连接,让高带宽能真正的服务于http的性能
- 服务器推送是什么?
把客户端所需要的资源伴随着index.html文件一起发送到客户端,省去客户端重新请求的过程
浏览器中有一个很重要的概念–同源策略,所谓的同源是指,域名,协议,端口相同。不同源的客户端脚本在没有明确授权的情况下不能读写对方的资源,只能去访问同源的文件
在https://www.baidu.com/中,其中的http指的是协议,www.baidu.com指的是域名,在.com后面加上:440。这个表示的就是默认的端口号,如果是默认的端口号,则不需要在访问网站的时候去写端口号。
-
http默认的端口号是:80
-
https的默认的端口号是:443 https是在http的基础上加了SSL层而形成的,其安全性更高
-
域名解析,在进行域名解析时,其解析的过程是倒着解析的
一级域名 .com 二级域名 baidu.com 三级域名 zhidao.baidu.com
相关域名代表的含义
com org net 属于顶级域名,是在全世界范围内解析的,cn hk是在一个地区解析的,如:
-
.cn 中国
-
.com(商业机构)
-
.net(从事互联网服务的机构)
-
.org(非盈利性组织)
-
.com.cn (国内商业机构)
-
.net.cn(国内从事互联网服务机构)
-
.net.org(国内非盈利性组织)
dns先根据顶级域名判断网络范围再根据域名查找主机ip地址,理论上www开头相当于占用为的 在国外一般不写www
同源策略的解决方式:
-
flash现目前不常用,因此不做讨论
-
服务器代理中转
-
jsonp
-
document.domain(针对基础域名相同的情况)
bj.58.com document.domain = ‘58.com’
tj.58.com document.domain = ‘58.com’
各种跨域的实现原理与方法
服务器代理中转:
首先明白的一点就是同源策略是浏览器与服务器中间存在的,而服务器与服务器之间不存在同源策略问题。因此如果想要实现从浏览器跨域到其他服务器,可以采用的方式是先将浏览器中的请求发送给与自己端口、协议、域名相同的服务器当中,再通过这个服务器与其他服务器进行数据之间的请求,从而就能实现跨域的过程document.domain(针对基础域名相同的情况)采用这种方式去处理跨域问题时,必须有一个要求就是基础域名必须是相同的情况下,才能够用这种方式
JSONP原理:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
最后的最后
面试题千万不要死记,一定要自己理解,用自己的方式表达出来,在这里预祝各位成功拿下自己心仪的offer。
需要完整面试题的朋友可以点击蓝色字体获取
k是在一个地区解析的,如:
-
.cn 中国
-
.com(商业机构)
-
.net(从事互联网服务的机构)
-
.org(非盈利性组织)
-
.com.cn (国内商业机构)
-
.net.cn(国内从事互联网服务机构)
-
.net.org(国内非盈利性组织)
dns先根据顶级域名判断网络范围再根据域名查找主机ip地址,理论上www开头相当于占用为的 在国外一般不写www
同源策略的解决方式:
-
flash现目前不常用,因此不做讨论
-
服务器代理中转
-
jsonp
-
document.domain(针对基础域名相同的情况)
bj.58.com document.domain = ‘58.com’
tj.58.com document.domain = ‘58.com’
各种跨域的实现原理与方法
服务器代理中转:
首先明白的一点就是同源策略是浏览器与服务器中间存在的,而服务器与服务器之间不存在同源策略问题。因此如果想要实现从浏览器跨域到其他服务器,可以采用的方式是先将浏览器中的请求发送给与自己端口、协议、域名相同的服务器当中,再通过这个服务器与其他服务器进行数据之间的请求,从而就能实现跨域的过程document.domain(针对基础域名相同的情况)采用这种方式去处理跨域问题时,必须有一个要求就是基础域名必须是相同的情况下,才能够用这种方式
JSONP原理:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-TNgY7oyE-1712651153247)]
[外链图片转存中…(img-Z88RjL1I-1712651153247)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
[外链图片转存中…(img-CT08kCyX-1712651153248)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
最后的最后
面试题千万不要死记,一定要自己理解,用自己的方式表达出来,在这里预祝各位成功拿下自己心仪的offer。
需要完整面试题的朋友可以点击蓝色字体获取
[外链图片转存中…(img-6poTmTKC-1712651153248)]
[外链图片转存中…(img-PaWwPbWy-1712651153248)]
[外链图片转存中…(img-TpEMqccD-1712651153249)]
[外链图片转存中…(img-I6PYZZUc-1712651153249)]