1、前端跨域问题
同源策略(协议http + 子域名www.或b2c. + 主域名lanmeiairlines.com + 端口号 要相同)
跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。
但是有三个标签是允许跨域加载资源:
<imgsrc=XXX>
<linkhref=XXX>
<scriptsrc=XXX>
1.通过jsonp跨域(只能解决get)
2.跨域资源共享(CORS),后台配置
3.nginx代理跨域
4.window.name + iframe跨域
5.postMessage跨域
6.document.domain + iframe跨域
7.location.hash + iframe
8.nodejs中间件代理跨域
9.WebSocket协议跨域
2、图片预加载和懒加载
$.preloadImages = function(){
for (var i = 0; i <arguments.length; i++) {
$('img').attr('src',arguments[i]);
}
};
$.preloadImages('img01.png','img02.png');
$('.imgload').load(function(){
console.log('加载成功');
});
$('.imgload').on('error',function(){
console.log('加载失败');
if(!$(this).hasClass('broken-image')){
$(this).prop('src','city-to.png').addClass('broken-image');
}
});
3、函数节流和防抖
高频事件:scroll mousewhell mousemover touchmove onresize,
防抖应用的例子:判断用户的输入情况,只在用户停止输入一段时间后再进行判断。
节流应用的例子:滚动页面垂直滚动条,判断是否滚动到页面底部。
1.函数节流是指一定时间内js方法只跑一次。比如人的眨眼睛,就是一定时间内眨一次。这是函数节流最形象的解释。
var canRun = true;
document.getElementById("throttle").onscroll = function(){
if(!canRun){
// 判断是否已空闲,如果在执行中,则直接return
return;
}
canRun = false;
setTimeout(function(){
console.log("函数节流");
canRun = true;
}, 300);
};
函数节流的要点是,声明一个变量当标志位,记录当前代码是否在执行。
如果空闲,则可以正常触发方法执行。
如果代码正在执行,则取消这次方法执行,直接return。
2.函数防抖是指频繁触发的情况下,只有足够的空闲时间,才执行代码一次。比如生活中的坐公交,就是一定时间内,如果有人陆续刷卡上车,司机就不会开车。只有别人没刷卡了,司机才开车。比如:用户输入时,输入频率太快就先别发请求
var timer = false;
document.getElementById("debounce").oninput = function(){
clearTimeout(timer); // 清除未执行的代码,重置回初始化状态
timer = setTimeout(function(){
console.log("函数防抖");
}, 300);
};
4、get/post的区别
1.get数据是存放在url之后,以?分割url和传输数据,参数之间以&相连; post方法是把提交的数据放在http包的Body中
2.get提交的数据大小有限制,(因为浏览器对url的长度有限制),post的方法提交的数据没有限制
3.get需要request.queryString来获取变量的值,而post方式通过request.from来获取变量的值
4.get的方法提交数据,会带来安全问题,比如登录一个页面,通过get的方式提交数据,用户名和密码就会出现在url上
5、常见的web安全及防护原理
1.sql注入原理:通郭sql命令插入到web表单递交或者输入活命,达到欺骗服务器执行的恶意sql命令 防范:1.对用户输入进行校验 2.不适用动态拼接sql
2.XSS(跨站脚本攻击):往web页面插入恶意的html标签或者js代码。 举例子:在论坛放置一个看是安全的链接,窃取cookie中的用户信息 防范:1.尽量采用post而不使用get提交表单 2.httpOnly,禁止用document.cookie操作;输入检查:在用户输入的时候进行格式检查;对输出转义。
3.CSRF(跨站请求伪装):通过伪装来自受信任用户的请求。防范:在客服端页面增加伪随机数,通过验证码;检查 Referer 字段;添加校验 Token
6、从输入url到获取页面的完整过程
1.查询DNS(域名解析),获取域名对应的IP地址 查询浏览器缓存 —应用层
2.浏览器与服务器建立TCP连接(三次握手) —传输层
3.浏览器向服务器发送http请求(请求和传输数据)
4.服务器接受到这个请求后,根据路经参数,经过后端的一些处理生成html代码返回给浏览器
5.浏览器拿到完整的html页面代码开始解析和渲染,如果遇到外部的css或者js,图片一样的步骤
6.浏览器根据拿到的资源对页面进行渲染,把一个完整的页面呈现出来
7、TCP三次握手
第一次握手:客服端发送一个请求连接,服务器端只能确认自己可以接受客服端发送的报文段
第二次握手: 服务端向客服端发送一个链接,确认客服端收到自己发送的报文段
第三次握手: 服务器端确认客服端收到了自己发送的报文段
8、存储方式
1、cookie,sessionStorage,localStorage是存放在客户端,session对象数据是存放在服务器上实际上浏览器和服务器之间仅需传递session id即可,服务器根据session-id找到对应的用户session对象session存储数据更安全一些,一般存放用户信息,浏览器只适合存储一般的数据
2、cookie数据始终在同源的http请求中携带,在浏览器和服务器来回传递,里面存放着session-id,sessionStorage,localStorage仅在本地保存
3、大小限制区别,cookie数据不超过4kb,localStorage在谷歌浏览中2.6MB
4、数据有效期不同,cookie在设置的(服务器设置)有效期内有效,不管窗口和浏览器关闭sessionStorage仅在当前浏览器窗口关闭前有效,关闭即销毁(临时存储)localStorage始终有效
基于Token的身份验证:(最简单的token: uid用户唯一的身份识别 + time当前事件戳 + sign签名)
1、用户通过用户名和密码发送请求
2、服务器端验证
3、服务器端返回一个带签名的token,给客户端
4、客户端储存token,并且每次用于发送请求
5、服务器验证token并且返回数据
每一次请求都需要token
cookie与session区别
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
9、http常见状态代码
200 OK:客户端请求成功。
301重定向是永久的重定向,302重定向是临时的重定向
400 Bad Request:客户端请求有语法错误,不能被服务器所理解。
401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用。
403 Forbidden:服务器收到请求,但是拒绝提供服务。
404 Not Found:请求资源不存在,举个例子:输入了错误的URL。
500 Internal Server Error:服务器发生不可预期的错误。
503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,举个例子:HTTP/1.1 200 OK(CRLF)。
10、iframe有那些缺点?
iframe会阻塞主页面的Onload事件;
搜索引擎的检索程序无法解读这种页面,不利于SEO;
iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载。
使用iframe之前需要考虑这两个缺点。如果需要使用iframe,最好是通过javascript动态
给iframe添加src属性值,这样可以绕开以上两个问题。
11、前端性能优化
1、首先最基本的,CSS样式表放在页面头部Head内且link链式引入,javascript放在底部body结束标签前避免阻塞。
2、js/html/css/图片都做压缩合并,图片预加载、懒加载,也是老生常谈了,在这里推荐一个图片无损极限压缩的工具,能压小60~80%左右,比较麻烦的是每次要手动操作——TinyPNG
3、减少DOM元素数量,减少DOM的操作:
4、静态资源CDN分发:
5、域名拆分:
6、 减少http请求次数
合并 JS、CSS 文件;
图片/图标 sprites 合并,或使用iconfont字体图标,或者SVG Sprites;什么是Svg Sprites?;
资源按需加载,即当前页面用到什么,就加载什么,避免加载与当前页面无关的事情,这一点现在的React/Vue/Angular等MVVM框架,基于webpack编译打包工具,做的很好;
前端数据的缓存(如:一个列表页,进入详情,再返回,这个用户的交互行为是很频繁的,可以对列表的数据进度一个缓存,不用每次返回都进行加载,比如5分钟更新一次。
7、 数据设置缓存,好累写不动了,http缓存的设置,之前的面试汇总如何设置http缓存?吧;
8、 站点服务端开启Gzip压缩,当然还可以了解一下Brotli 或 Zopfli ,据说 Brotli 比 Gzip 和 Deflate更有效,有兴趣的同学可以了解一下;
8、 避免重定向,尽量减少 iframe 使用,它会阻塞主页面的渲染;
12、请用js去除字符串空格?
方法一:使用replace正则匹配的方法
去除所有空格: str = str.replace(/\s*/g,"");
去除两头空格: str = str.replace(/^\s*|\s*KaTeX parse error: Undefined control sequence: \s at position 37: …str.replace( /^\̲s̲*/, “”); 去除右空格:…)/g, “”);
str为要去除空格的字符串,实例如下:
var str = " 23 23 “;var str2 = str.replace(/\s*/g,”");console.log(str2); // 2323
方法二:使用str.trim()方法
str.trim()局限性:无法去除中间的空格,实例如下:
var str = " xiao ming ";var str2 = str.trim(); console.log(str2); //xiao ming
同理,str.trimLeft(),str.trimRight()分别用于去除字符串左右空格。
方法三:使用jquery,$.trim(str)方法
$.trim(str)局限性:无法去除中间的空格,实例如下:
var str = " xiao ming ";
var str2 = $.trim(str)
console.log(str2); // xiao ming
13、你如何获取浏览器URL中查询字符串中的参数?
function showWindowHref(){
var sHref = window.location.href;
var args = sHref.split('?');
if(args[0] == sHref){
return "";
}
var arr = args[1].split('&');
var obj = {};
for(var i = 0;i< arr.length;i++){
var arg = arr[i].split('=');
obj[arg[0]] = arg[1];
}
return obj;
}
var href = showWindowHref(); // obj
console.log(href['name']); // xiaoming
14、数组去重
方法一:
var arr = [0,2,3,4,4,0,2];
var obj = {};
var tmp = [];
for(var i = 0 ;i< arr.length;i++){
if( !obj[arr[i]] ){
obj[arr[i]] = 1;
tmp.push(arr[i]);
}
}
console.log(tmp);
方法二:
var arr = [2,3,4,4,5,2,3,6],
arr2 = [];
for(var i = 0;i< arr.length;i++){
if(arr2.indexOf(arr[i]) < 0){
arr2.push(arr[i]);
}
}
console.log(arr2);
方法三:
var arr = [2,3,4,4,5,2,3,6];
var arr2 = arr.filter(function(element,index,self){
return self.indexOf(element) === index;
});
console.log(arr2);
方法四:ES6——new Set方法
const myArray = [1,1,2,2,3,3,4,4,5,5]
console.log([...new Set(myArray )]);// [1, 2, 3, 4, 5]
方法五:Array.from(该方法可以将 Set 结构转为数组)
function dedupe(array) {
return Array.from(new Set(array));
}
dedupe([1, 1, 2, 3]) // [1, 2, 3]
15、渐进增强 VS 优雅降级
渐进增强(Progressive Enhancement):一开始就针对低版本浏览器进行构建页面,完成基本的功能,然后再针对高级浏览器进行效果、交互、追加功能达到更好的体验。
优雅降级(Graceful Degradation):一开始就构建站点的完整功能,然后针对浏览器测试和修复。比如一开始使用 CSS3 的特性构建了一个应用,然后逐步针对各大浏览器进行 hack 使其可以在低版本浏览器上正常浏览。
16、HTTP与HTTPS的区别
Http 协议运行在 TCP 之上,明文传输,客户端与服务器端都无法验证对方的身份;Https 是身披 SSL(Secure Socket Layer)外壳的 Http,运行于 SSL 上,SSL 运行于 TCP 之上,是添加了加密和认证机制的 HTTP。二者之间存在如下不同:
端口不同:Http 与 Http 使用不同的连接方式,用的端口也不一样,前者是 80,后者是 443;
资源消耗:和 HTTP 通信相比,Https 通信会由于加减密处理消耗更多的 CPU 和内存资源;
开销:Https 通信需要证书,而证书一般需要向认证机构购买;
Https 的加密机制是一种共享密钥加密和公开密钥加密并用的混合加密机制。
17、JSON
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。
它是基于JavaScript的一个子集。数据格式简单, 易于读写, 占用带宽小
// JSON字符串转换为JSON对象:
var obj =eval('('+ str +')');
var obj = str.parseJSON();
var obj = JSON.parse(str);
// JSON对象转换为JSON字符串:
var last=obj.toJSONString();
var last=JSON.stringify(obj);