共计 3469 个字符,预计需要花费 9 分钟才能阅读完成。
什么是跨域?跨域请求资源的方法有哪些?
1、什么是跨域?由于浏览器同源策略,凡是发送请求 url 的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。存在跨域的情况:网络协议不同,如 http 协议访问 https 协议。端口不同,如 80 端口访问 8080 端口。域名不同,如 qianduanblog.com 访问 baidu.com。子域名不同,如 abc.qianduanblog.com 访问 def.qianduanblog.com。域名和域名对应 ip, 如 www.a.com 访问 20.205.28.90.2、跨域请求资源的方法:(1)、porxy 代理定义和用法:proxy 代理用于将请求发送给后台服务器,通过服务器来发送请求,然后将请求的结果传递给前端。实现方法:通过 nginx 代理;注意点:1、如果你代理的是 https 协议的请求,那么你的 proxy 首先需要信任该证书(尤其是自定义证书)或者忽略证书检查,否则你的请求无法成功。(2)、CORS【Cross-Origin Resource Sharing】定义和用法:是现代浏览器支持跨域资源请求的一种最常用的方式。使用方法:一般需要后端人员在处理请求数据的时候,添加允许跨域的相关操作。如下:
res.writeHead(200, {
“Content-Type”: “text/html; charset=UTF-8”,
“Access-Control-Allow-Origin”:’http://localhost’,
‘Access-Control-Allow-Methods’: ‘GET, POST, OPTIONS’,
‘Access-Control-Allow-Headers’: ‘X-Requested-With, Content-Type’
});
(3)、jsonp 定义和用法:通过动态插入一个 script 标签。浏览器对 script 的资源引用没有同源限制,同时资源加载到页面后会立即执行(没有阻塞的情况下)。特点:通过情况下,通过动态创建 script 来读取他域的动态资源,获取的数据一般为 json 格式。实例如下:
<script>
function testjsonp(data) {
console.log(data.name); // 获取返回的结果
}
</script>
<script>
var _script = document.createElement(‘script’);
_script.type = “text/javascript”;
_script.src = “http://localhost:8888/jsonp?callback=testjsonp”;
document.head.appendChild(_script);
</script>
缺点:1、这种方式无法发送 post 请求(这里)2、另外要确定 jsonp 的请求是否失败并不容易,大多数框架的实现都是结合超时时间来判定。
介绍一下 JS 的基本数据类型。
Undefined、Null、Boolean、Number、String
如何利用 JavaScript 实现一个自定义事件,存在 on,off,emit 三个方法?
这个题目的意义在哪里?我想,应该是对于一些特定的业务逻辑,比如在注册一个“通知”的事件,在与 Native 交互之后,假设这个交互是在入口级别的页面里,那么如何发送给具体某个业务呢?事件应该是最简单的一种方式,在某个具体的业务中注册一个事件,然后在与 Native 交互完,拿到某些数据后,然后触发这个事件。
我们来一步一步实现一个最简单的事件类 Event,不考虑任何其他复杂的情况。假设在这个 Event 类的内部有一个 this._events = [] 数组来维系整个事件系统,我们分别实现 on,off,emit 三个方法即可。
on(注册一个事件):
Event.prototype.on = function(type,fun){
let cbs = this._events[type];
cbs ? cbs.push(fun) : this._events[type] = [];
if (!cbs) {
this._events[type].push(fun)
}
}
这里为什么要将 this._events 设计为二维数组?因为事件可以是多个,但是事件名可能相同。这个逻辑意图非常的明显,根据 type 参数从 this._events 中获取是否存在。如果不存在,创建一个 type 为 key 的数组,并将事件句柄程序 push 到数组中。
off(注销一个事件):
Event.prototype.off = function(type,fun){
let cbs = this._events[type];
// 事件列队中无事件
if (!cbs) {
return this;
}
// 删除所有的事件
if (!event && !fun) {
this._events = {};
return this;
}
// 只有事件名称时
if (event && !fun) {
this._events[type] = null;
return this;
}
// 删除某个事件队列中的某个事件
let cb;
let i = cbs.length;
while(i–){
cb = cbs[i];
if (cb === fun || cb.fun === fun) {
cbs.splice(i,1);
break;
}
}
}
虽然注销事件方法的逻辑可能相比之下稍许多了些,但它的实现也非常简单,只要只存在事件组 key 名的情况,或者删除某个事件队列中的某个事件句柄程序即可。
emit(触发一个事件):
Event.prototype.emit = function(type){
let cbs = this._events[type];
let args = tools.toArray(arguments,1);
if (cbs) {
let i = 0;
let j = cbs.length;
for(;i<j;i++){
let cb = cbs[i];
cb.apply(this,args);
}
}
}
逻辑依然非常简单,通过事件名从 this._events 获取相应的事件句柄程序数组,然后将 arguments 转成数组,(这里考虑的是可能会传入参数)如果事件句柄程序数组存在,进行循环,再讲 args 参数 apply 给每一个取出来的事件句柄程序。
请描述一个网页从开始请求道最终显示的完整过程?
一个网页从请求到最终显示的完整过程一般可以分为如下 7 个步骤:
(1)在浏览器中输入网址;
(2)发送至 DNS 服务器并获得域名对应的 WEB 服务器 IP 地址;
(3)与 WEB 服务器建立 TCP 连接;
(4)浏览器向 WEB 服务器的 IP 地址发送相应的 HTTP 请求;
(5)WEB 服务器响应请求并返回指定 URL 的数据,或错误信息,如果设定重定向,则重定向到新的 URL 地址;
(6)浏览器下载数据后解析 HTML 源文件,解析的过程中实现对页面的排版,解析完成后在浏览器中显示基础页面;
(7)分析页面中的超链接并显示在当前页面,重复以上过程直至无超链接需要发送,完成全部数据显示。
请描述一下 cookies,sessionStorage 和 localStorage 的区别?
Web Storage 有两种形式:LocalStorage(本地存储)和 sessionStorage(会话存储)。
这两种方式都允许开发者使用 js 设置的键值对进行操作,在在重新加载不同的页面的时候读出它们。这一点与 cookie 类似。
(1)与 cookie 不同的是:Web Storage 数据完全存储在客户端,不需要通过浏览器的请求将数据传给服务器,因此 x 相比 cookie 来说能够存储更多的数据,大概 5M 左右。
(2)LocalStorage 和 sessionStorage 功能上是一样的,但是存储持久时间不一样。
LocalStorage:浏览器关闭了数据仍然可以保存下来,并可用于所有同源(相同的域名、协议和端口)窗口(或标签页);
sessionStorage:数据存储在窗口对象中,窗口关闭后对应的窗口对象消失,存储的数据也会丢失。
注意:sessionStorage 都可以用 localStorage 来代替,但需要记住的是,在窗口或者标签页关闭时,使用 sessionStorage 存储的数据会丢失。
(3)使用 local storage 和 session storage 主要通过在 js 中操作这两个对象来实现,分别为 window.localStorage 和 window.sessionStorage. 这两个对象均是 Storage 类的两个实例,自然也具有 Storage 类的属性和方法。