js基础面试题

(掌握)什么是“use strict”,好处和坏处

use ‘strict’: "严格模式"是一种在JavaScript代码运行时自动实行更严格解析和错误处理的方法。

优点:

  1. 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;

  2. 消除代码运行的一些不安全之处,保证代码运行的安全;

  3. 提高编译器效率,增加运行速度;

  4. 为未来新版本的Javascript做好铺垫。

缺点:

现在网站的 JS 都会进行压缩,一些文件用了严格模式,而另一些没有。这时这些本来是严格模式的文件,被 merge 后,这个字符串("use strict")就到了文件的中间,不仅没有指示严格模式,反而在压缩后浪费了字节。

(掌握)console.log(0.1 + 0.2)

0.1+0.2的结果不是0.3,而是0.3000000000000000004,JS中两个数字相加时是以二进制形式进行的,当十进制小数的二进制表示的有限数字超过52位时,在JS里是不能精确储存的,这个时候就存在舍入误差。

(掌握)数组pop(), push(), unshift(), shift()的区别

  • push()方法可以在数组的末属添加一个或多个元素
  • shift()方法把数组中的第一个元素删除
  • unshift()方法可以在数组的前端添加一个或多个元素
  • pop()方法把数组中的最后一个元素删除

(掌握)==和===

  1. ==:只是比较值
  2. ===:既要比较数据类型还要比较值

掌握)事件冒泡和事件捕获到底有何区别?

  1. 事件冒泡:从下至上。当给父子元素的同一事件绑定方法的时候,触发子元素身上的事件,执行完毕之后,也会触发父级元素相同的事件。

注意: addEventListener中有三个属性,第三个属性是布尔值。false为事件冒泡,true为事件捕获

  1. 事件捕获:从上至下到指定元素。当触发子元素身上的事件时,先触发父元素,然后在传递给子元素

(掌握)JS数据类型

在ES5的时候,我们认知的数据类型确实是 6种:Number、String、Boolean、undefined、object、Null。

ES6 中新增了一种 Symbol 。这种类型的对象永不相等,即始创建的时候传入相同的值,可以解决属性名冲突的问题,做为标记。

(掌握)什么是typescript

  • 1.它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。
  • 2.TypeScript扩展了JavaScript的语法,所以任何现有的JavaScript程序可以不加改变的在TypeScript下工作。TypeScript是为大型应用之开发而设计,而编译时它产生 JavaScript 以确保兼容性。

(掌握)什么是模块化编程?

每个模块内部,module变量代表当前模块。

这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,其实是加载该模块的module.exports属性。

(掌握)简述javascript原型、原型链?有什么特点

原型:每一个构造函数都有一个prototype属性指向一个对象,这个对象就是构造函数实例的原型

原型链:每一个实例都有一个proto属性执行原型对象,来获取原型对象上的属性和方法,原型对象也有一个__proto

属性指向另外一个原型对象,以此类推,直到原型链的最终端null为止,这个串成链的过程就是原型链

特点:实现继承 一个对象可以拿到另一个对象上的属性和方法

构造函数都有一个prototype属性指向原型对象

原型对象都有一个consttuctor属性指向构造函数

构造函数new实例化实例对象

实例对象上有__proto属性指向原型

(掌握)解释javascript中的作用域和变量声明提升

作用域是指程序源代码中定义变量的区域。作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。

变量声明提升:

foo;  // undefined
var foo = function () {
    console.log('foo1');
}

foo();  // foo1,foo赋值

可以想象成:所有的声明(变量和函数)都会被“移动”到各自作用域的最顶端。

(掌握)谈谈this对象的理解,call()和apply()的区别

call和apply的区别在于传入参数的不同; 第一个参数都是,指定函数体内this的指向;

第二个参数开始不同,apply是传入带下标的集合,数组或者类数组,apply把它传给函数作为参数,call从第二个开始传入的参数是不固定的,都会传给函数作为参数。

call比apply的性能要好,平常可以多用call。call传入参数的格式正是内部所需要的格式。

(掌握)js 的typeof返回有哪些数据类型?

string,number,Boolean,undefined,object,function, symbol(es6)

(掌握)什么是闭包?为什么要用它?

1)什么是闭包

函数执行后返回结果是一个内部函数,并被外部变量所引用,如果内部函数持有被执行函数作用域的变量,即形成了闭包。

可以在内部函数访问到外部函数作用域。使用闭包,一可以读取函数中的变量,二可以将函数中的变量存储在内存中,保护变量不被污染。而正因闭包会把函数中的变量值存储在内存中,会对内存有消耗,所以不能滥用闭包,否则会影响网页性能,造成内存泄漏。当不需要使用闭包时,要及时释放内存,可将内层函数对象的变量赋值为null。

**2)闭包原理 **

函数执行分成两个阶段(预编译阶段和执行阶段)。

  • 在预编译阶段,如果发现内部函数使用了外部函数的变量,则会在内存中创建一个“闭包”对象并保存对应变量值,如果已存在“闭包”,则只需要增加对应属性值即可。
  • 执行完后,函数执行上下文会被销毁,函数对“闭包”对象的引用也会被销毁,但其内部函数还持用该“闭包”的引用,所以内部函数可以继续使用“外部函数”中的变量

利用了函数作用域链的特性,一个函数内部定义的函数会将包含外部函数的活动对象添加到它的作用域链中,函数执行完毕,其执行作用域链销毁,但因内部函数的作用域链仍然在引用这个活动对象,所以其活动对象不会被销毁,直到内部函数被烧毁后才被销毁。

3)优点

  1. 可以从内部函数访问外部函数的作用域中的变量,且访问到的变量长期驻扎在内存中,可供之后使用
  2. 避免变量污染全局
  3. 把变量存到独立的作用域,作为私有成员存在

**4)缺点 **

  1. 对内存消耗有负面影响。因内部函数保存了对外部变量的引用,导致无法被垃圾回收,增大内存使用量,所以使用不当会导致内存泄漏
  2. 对处理速度具有负面影响。闭包的层级决定了引用的外部变量在查找时经过的作用域链长度
  3. 可能获取到意外的值(captured value)

4)应用场景

应用场景一: 典型应用是模块封装,在各模块规范(ES6)出现之前,都是用这样的方式防止变量污染全局。

var Yideng = (function () {
    // 这样声明为模块私有变量,外界无法直接访问
    var foo = 0;

    function Yideng() {}
    Yideng.prototype.bar = function bar() {
        return foo;
    };
    return Yideng;
}());

应用场景二: 在循环中创建闭包,防止取到意外的值。

如下代码,无论哪个元素触发事件,都会弹出 3。因为函数执行后引用的 i 是同一个,而 i 在循环结束后就是 3

for (var i = 0; i < 3; i++) {
    document.getElementById('id' + i).onfocus = function() {
      alert(i);
    };
}
//可用闭包解决
function makeCallback(num) {
  return function() {
    alert(num);
  };
}
for (var i = 0; i < 3; i++) {
    document.getElementById('id' + i).onfocus = makeCallback(i);
}

(掌握)简述js继承的方式

  1. 混入式继承:把父类的所有方法都拷贝到子类上
  2. 原型式继承:只继承父类原型上的属性和方法
  3. 原型链继承:继承父类构造函数里边的属性和方法,也继承父类原型上的属性和方法 缺点--不能向父类传参数
  4. 借用构造函数继承:可以父类传递参数 缺点--继承不了父类原型对象的方法
  5. 组合继承:借用构造函数继承+原型链继承

(掌握)给String添加一个trim()方法,去除开头和结尾的空格符号

String.prototype.trim = function (str) {
  return str.replace(/(^\s*)|(\s*$)/g, '');
}

(掌握)深拷贝和浅拷贝的区别

浅拷贝(shallowCopy)只是增加了一个指针指向已存在的内存地址,

深拷贝(deepCopy)是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存.

浅复制:仅仅是指向被复制的内存地址,如果原地址发生改变,那么浅复制出来的对象也会相应的改变。

深复制:在计算机中开辟一块新的内存地址用于存放复制的对象。

(掌握)如何实现深拷贝

常用:使用JSON.parse(JSON.stringify(obj))

原理是把一个对象序列化成为一个JSON字符串,将对象的内容转换成字符串的形式再保存在磁盘上,再用JSON.parse()反序列化将JSON字符串变成一个新的对象

缺点是: 会忽略undefined、symbol、funciton

实现:递归+判断类型

一个简单的代码

// 数字 字符串 function是不需要拷贝的
function deepClone(value) {  
    if (value == null) return value;  
    if (typeof value !== 'object') return value;
    if (value instanceof RegExp) return new RegExp(value);  
    if (value instanceof Date) return new Date(value);  
    // 我要判断 value 是对象还是数组 如果是对象 就产生对象 是数组就产生数组  
    let obj = new value.constructor;  
    for(let key in value){    
        obj[key] = deepClone(value[key]); // 看一看当前的值是不是一个对象  
    }  
    return obj;
}

(掌握)javascript 的垃圾回收机制讲一下

定义:指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束。

JavaScript 在创建对象(对象、字符串等)时会为它们分配内存,不再使用对时会“自动”释放内存,这个过程称为垃圾收集。

内存生命周期中的每一个阶段:

分配内存 —  内存是由操作系统分配的,它允许您的程序使用它。在低级语言(例如 C 语言)中,这是一个开发人员需要自己处理的显式执行的操作。然而,在高级语言中,系统会自动为你分配内在。 使用内存 — 这是程序实际使用之前分配的内存,在代码中使用分配的变量时,就会发生读和写操作。 释放内存 — 释放所有不再使用的内存,使之成为自由内存,并可以被重利用。与分配内存操作一样,这一操作在低级语言中也是需要显式地执行。

四种常见的内存泄漏:全局变量,未清除的定时器,闭包,以及 dom 的引用

  1. 全局变量 不用 var 声明的变量,相当于挂载到 window 对象上。如:b=1; 解决:使用严格模式
  2. 被遗忘的定时器和回调函数
  3. 闭包
  4. 没有清理的 DOM 元素引用

介绍下 promise 的特性、优缺点

  • Promise基本特性

    1、Promise有三种状态:pending(进行中)、fulfilled(已成功)、rejected(已失败)

    2、Promise对象接受一个回调函数作为参数, 该回调函数接受两个参数,分别是成功时的回调resolve和失败时的回调reject;另外resolve的参数除了正常值以外, 还可能是一个Promise对象的实例;reject的参数通常是一个Error对象的实例。

    3、then方法返回一个新的Promise实例,并接收两个参数onResolved(fulfilled状态的回调);onRejected(rejected状态的回调,该参数可选)

    4、catch方法返回一个新的Promise实例

    5、finally方法不管Promise状态如何都会执行,该方法的回调函数不接受任何参数

    6、Promise.all()方法将多个多个Promise实例,包装成一个新的Promise实例,该方法接受一个由Promise对象组成的数组作为参数(Promise.all()方法的参数可以不是数组,但必须具有Iterator接口,且返回的每个成员都是Promise实例),注意参数中只要有一个实例触发catch方法,都会触发Promise.all()方法返回的新的实例的catch方法,如果参数中的某个实例本身调用了catch方法,将不会触发Promise.all()方法返回的新实例的catch方法

    7、Promise.race()方法的参数与Promise.all方法一样,参数中的实例只要有一个率先改变状态就会将该实例的状态传给Promise.race()方法,并将返回值作为Promise.race()方法产生的Promise实例的返回值

    8、Promise.resolve()将现有对象转为Promise对象,如果该方法的参数为一个Promise对象,Promise.resolve()将不做任何处理;如果参数thenable对象(即具有then方法),Promise.resolve()将该对象转为Promise对象并立即执行then方法;如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的Promise对象,状态为fulfilled,其参数将会作为then方法中onResolved回调函数的参数,如果Promise.resolve方法不带参数,会直接返回一个fulfilled状态的 Promise 对象。需要注意的是,立即resolve()的 Promise 对象,是在本轮“事件循环”(event loop)的结束时执行,而不是在下一轮“事件循环”的开始时。

    9、Promise.reject()同样返回一个新的Promise对象,状态为rejected,无论传入任何参数都将作为reject()的参数

    2)Promise优点

    ①统一异步 API

    • Promise 的一个重要优点是它将逐渐被用作浏览器的异步 API ,统一现在各种各样的 API ,以及不兼容的模式和手法。

    ②Promise 与事件对比

    • 和事件相比较, Promise 更适合处理一次性的结果。在结果计算出来之前或之后注册回调函数都是可以的,都可以拿到正确的值。 Promise 的这个优点很自然。但是,不能使用 Promise 处理多次触发的事件。链式处理是 Promise 的又一优点,但是事件却不能这样链式处理。

    ③Promise 与回调对比

    • 解决了回调地狱的问题,将异步操作以同步操作的流程表达出来。

    ④Promise 带来的额外好处是包含了更好的错误处理方式(包含了异常处理),并且写起来很轻松(因为可以重用一些同步的工具,比如 Array.prototype.map() )。

    3)Promise缺点

    1、无法取消Promise,一旦新建它就会立即执行,无法中途取消。

    2、如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。

    3、当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

    4、Promise 真正执行回调的时候,定义 Promise 那部分实际上已经走完了,所以 Promise 的报错堆栈上下文不太友好。

(掌握)请介绍一下XMLhttprequest对象

Ajax的核心是JavaScript对象XmlHttpRequest。该对象在Internet Explorer 5中首次引入,它是一种支持异步请求的技术。简而言之,XmlHttpRequest使您可以使用JavaScript向服务器提出请求并处理响应,而不阻塞用户。通过XMLHttpRequest对象,Web开发人员可以在页面加载以后进行页面的局部更新。

(掌握)请描述一下 cookiessessionStoragelocalStorage 的区别?

  1. cookie是浏览器自动携带在请求里发送给服务端去验证的

sessionStorage和localStorage不会自动携带

  1. cookie体积相对sessionStorage localStorage小
  2. 后端可以设置cookie之后,前端修改不了的;
  3. cookie可以设置过期时间
  4. cookie是用来做状态保持的,因为http请求时无状态的
  5. cookie是用户第一次访问服务器服务器颁发给浏览器的,第二次请求就会携带
  6. sessionStorage 存储在内存中 关闭浏览器数据会消失
  7. localStorage 关闭浏览器数据不会消失 需要手动去清除

(掌握)浏览器缓存策略

1)浏览器缓存策略

浏览器每次发起请求时,先在本地缓存中查找结果以及缓存标识,根据缓存标识来判断是否使用本地缓存。如果缓存有效,则使 用本地缓存;否则,则向服务器发起请求并携带缓存标识。根据是否需向服务器发起HTTP请求,将缓存过程划分为两个部分: 强制缓存和协商缓存,强缓优先于协商缓存。

  • 强缓存,服务器通知浏览器一个缓存时间,在缓存时间内,下次请求,直接用缓存,不在时间内,执行比较缓存策略。
  • 协商缓存,让客户端与服务器之间能实现缓存文件是否更新的验证、提升缓存的复用率,将缓存信息中的Etag和Last-Modified 通过请求发送给服务器,由服务器校验,返回304状态码时,浏览器直接使用缓存。

HTTP缓存都是从第二次请求开始的:

  • 第一次请求资源时,服务器返回资源,并在response header中回传资源的缓存策略;
  • 第二次请求时,浏览器判断这些请求参数,击中强缓存就直接200,否则就把请求参数加到request header头中传给服务器,看是否击中协商缓存,击中则返回304,否则服务器会返回新的资源。这是缓存运作的一个整体流程图:

[
img

(opens new window)](https://camo.githubusercontent.com/df822872ee2a8aef44c665f8fffd13c4cc4eb637bd8706ce4899e8eb72d2a431/687474703a2f2f696d672d7374617469632e796964656e6778756574616e672e636f6d2f77786170702f69737375652d696d672f7169642d382e706e67)

2)强缓存

  • 强缓存命中则直接读取浏览器本地的资源,在network中显示的是from memory或者from disk
  • 控制强制缓存的字段有:Cache-Control(http1.1)和Expires(http1.0)
  • Cache-control是一个相对时间,用以表达自上次请求正确的资源之后的多少秒的时间段内缓存有效。
  • Expires是一个绝对时间。用以表达在这个时间点之前发起请求可以直接从浏览器中读取数据,而无需发起请求
  • Cache-Control的优先级比Expires的优先级高。前者的出现是为了解决Expires在浏览器时间被手动更改导致缓存判断错误的问题。 如果同时存在则使用Cache-control。

3)强缓存-expires

  • 该字段是服务器响应消息头字段,告诉浏览器在过期时间之前可以直接从浏览器缓存中存取数据。
  • Expires 是 HTTP 1.0 的字段,表示缓存到期时间,是一个绝对的时间 (当前时间+缓存时间)。在响应消息头中,设置这个字段之后,就可以告诉浏览器,在未过期之前不需要再次请求。
  • 由于是绝对时间,用户可能会将客户端本地的时间进行修改,而导致浏览器判断缓存失效,重新请求该资源。此外,即使不考虑修改,时差或者误差等因素也可能造成客户端与服务端的时间不一致,致使缓存失效。
  • 优势特点
    • 1、HTTP 1.0 产物,可以在HTTP 1.0和1.1中使用,简单易用。
    • 2、以时刻标识失效时间。
  • 劣势问题
    • 1、时间是由服务器发送的(UTC),如果服务器时间和客户端时间存在不一致,可能会出现问题。
    • 2、存在版本问题,到期之前的修改客户端是不可知的。

4)强缓存-cache-control

  • 已知Expires的缺点之后,在HTTP/1.1中,增加了一个字段Cache-control,该字段表示资源缓存的最大有效时间,在该时间内,客户端不需要向服务器发送请求。

  • 这两者的区别就是前者是绝对时间,而后者是相对时间。下面列举一些 Cache-control 字段常用的值:(完整的列表可以查看MDN)

    • max-age:即最大有效时间。
    • must-revalidate:如果超过了 max-age 的时间,浏览器必须向服务器发送请求,验证资源是否还有效。
    • no-cache:不使用强缓存,需要与服务器验证缓存是否新鲜。
    • no-store: 真正意义上的“不要缓存”。所有内容都不走缓存,包括强制和对比。
    • public:所有的内容都可以被缓存 (包括客户端和代理服务器, 如 CDN)
    • private:所有的内容只有客户端才可以缓存,代理服务器不能缓存。默认值。
  • Cache-control 的优先级高于 Expires,为了兼容 HTTP/1.0 和 HTTP/1.1,实际项目中两个字段都可以设置。

  • 该字段可以在请求头或者响应头设置,可组合使用多种指令:

    • 可缓存性

      • public:浏览器和缓存服务器都可以缓存页面信息
      • private:default,代理服务器不可缓存,只能被单个用户缓存
      • no-cache:浏览器器和服务器都不应该缓存页面信息,但仍可缓存,只是在缓存前需要向服务器确认资源是否被更改。可配合private, 过期时间设置为过去时间。
      • only-if-cache:客户端只接受已缓存的响应
    • 到期

      • max-age=:缓存存储的最大周期,超过这个周期被认为过期。
      • s-maxage=:设置共享缓存,比如can。会覆盖max-age和expires。
      • max-stale[=]:客户端愿意接收一个已经过期的资源
      • min-fresh=:客户端希望在指定的时间内获取最新的响应
      • stale-while-revalidate=:客户端愿意接收陈旧的响应,并且在后台一部检查新的响应。时间代表客户端愿意接收陈旧响应 的时间长度。
      • stale-if-error=:如新的检测失败,客户端则愿意接收陈旧的响应,时间代表等待时间。
    • 重新验证和重新加载

      • must-revalidate:如页面过期,则去服务器进行获取。
      • proxy-revalidate:用于共享缓存。
      • immutable:响应正文不随时间改变。
    • 其他

      • no-store:绝对禁止缓存
      • no-transform:不得对资源进行转换和转变。例如,不得对图像格式进行转换。
  • 优势特点

    • 1、HTTP 1.1 产物,以时间间隔标识失效时间,解决了Expires服务器和客户端相对时间的问题。
    • 2、比Expires多了很多选项设置。
  • 劣势问题

    • 1、存在版本问题,到期之前的修改客户端是不可知的。

5)协商缓存

  • 协商缓存的状态码由服务器决策返回200或者304
  • 当浏览器的强缓存失效的时候或者请求头中设置了不走强缓存,并且在请求头中设置了If-Modified-Since 或者 If-None-Match 的时候,会将这两个属性值到服务端去验证是否命中协商缓存,如果命中了协商缓存,会返回 304 状态,加载浏览器缓存,并且响应头会设置 Last-Modified 或者 ETag 属性。
  • 对比缓存在请求数上和没有缓存是一致的,但如果是 304 的话,返回的仅仅是一个状态码而已,并没有实际的文件内容,因此 在响应体体积上的节省是它的优化点。
  • 协商缓存有 2 组字段(不是两个),控制协商缓存的字段有:Last-Modified/If-Modified-since(http1.0)和Etag/If-None-match(http1.1)
  • Last-Modified/If-Modified-since表示的是服务器的资源最后一次修改的时间;Etag/If-None-match表示的是服务器资源的唯一标 识,只要资源变化,Etag就会重新生成。
  • Etag/If-None-match的优先级比Last-Modified/If-Modified-since高。

6)协商缓存-协商缓存-Last-Modified/If-Modified-since

  • 1.服务器通过 Last-Modified 字段告知客户端,资源最后一次被修改的时间,例如 Last-Modified: Mon, 10 Nov 2018 09:10:11 GMT
  • 2.浏览器将这个值和内容一起记录在缓存数据库中。
  • 3.下一次请求相同资源时时,浏览器从自己的缓存中找出“不确定是否过期的”缓存。因此在请求头中将上次的 Last-Modified 的值写入到请求头的 If-Modified-Since 字段
  • 4.服务器会将 If-Modified-Since 的值与 Last-Modified 字段进行对比。如果相等,则表示未修改,响应 304;反之,则表示修改了,响应 200 状态码,并返回数据。
  • 优势特点
    • 1、不存在版本问题,每次请求都会去服务器进行校验。服务器对比最后修改时间如果相同则返回304,不同返回200以及资源内容。
  • 劣势问题
    • 2、只要资源修改,无论内容是否发生实质性的变化,都会将该资源返回客户端。例如周期性重写,这种情况下该资源包含的数据实际上一样的。
    • 3、以时刻作为标识,无法识别一秒内进行多次修改的情况。 如果资源更新的速度是秒以下单位,那么该缓存是不能被使用的,因为它的时间单位最低是秒。
    • 4、某些服务器不能精确的得到文件的最后修改时间。
    • 5、如果文件是通过服务器动态生成的,那么该方法的更新时间永远是生成的时间,尽管文件可能没有变化,所以起不到缓存的作用。

7)协商缓存-Etag/If-None-match

  • 为了解决上述问题,出现了一组新的字段 EtagIf-None-Match
  • Etag 存储的是文件的特殊标识(一般都是 hash 生成的),服务器存储着文件的 Etag 字段。之后的流程和 Last-Modified 一致,只是 Last-Modified 字段和它所表示的更新时间改变成了 Etag 字段和它所表示的文件 hash,把 If-Modified-Since 变成了 If-None-Match。服务器同样进行比较,命中返回 304, 不命中返回新资源和 200。
  • 浏览器在发起请求时,服务器返回在Response header中返回请求资源的唯一标识。在下一次请求时,会将上一次返回的Etag值赋值给If-No-Matched并添加在Request Header中。服务器将浏览器传来的if-no-matched跟自己的本地的资源的ETag做对比,如果匹配,则返回304通知浏览器读取本地缓存,否则返回200和更新后的资源。
  • Etag 的优先级高于 Last-Modified
  • 优势特点
    • 1、可以更加精确的判断资源是否被修改,可以识别一秒内多次修改的情况。
    • 2、不存在版本问题,每次请求都回去服务器进行校验。
  • 劣势问题
    • 1、计算ETag值需要性能损耗。
    • 2、分布式服务器存储的情况下,计算ETag的算法如果不一样,会导致浏览器从一台服务器上获得页面内容后到另外一台服务器上进行验证时现ETag不匹配的情况。

(掌握)简述同源策略与跨域

同源策略是一种约定,它是浏览器最核心的也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能会受到影响。

当协议,主机,和端口号有一个不同时,就是跨域。

(掌握)跨域解决方案

1、(后端)服务器配置CORS(跨域资源共享)

2) (后端)node.js或nginx,反向代理,把跨域改造成同域

3)(前端)将JSON升级成JSONP,在JSON的基础上,利用

你可能感兴趣的:(js基础面试题)