前端技术是Web应用开发中基于浏览器的程序开发,涵盖HTML、CSS和JavaScript等基础技术,并通过BOM、DOM实现用户交互。该技术以HTML、CSS、JavaScript为核心基础,通过DOM与BOM实现动态页面控制。

HTML5的新特性和CSS3的新特性

HTML5的新特性

  • 语义化标签 :headernavasidefooterarticlesection 等。可以更清晰地描述网页的结构和内容,提高网页的可读性和可访问性,利于搜索引擎优化(SEO)。
  • **表单控件验证功能:**如日期选择器、颜色选择器、滑块等,表单更加易用,同时内置表单验证功能,减少了验证代码的编写量。
  • 多媒体支持: video audio等

CSS3的新特性

  • 改善布局和样式: 如边框圆角、边框阴影、渐变、文本装饰
  • 动画和过渡: transition 属性和 @keyframes 规则制定动画效果
  • 多列布局和弹性盒子布局
  • 媒体查询: 不同屏幕的尺寸使用不同的css
  • 自定义字体和背景
  • **网格布局 :*上下居中水平对齐方式display: grid; place-items: center; / 水平和垂直都居中 */

css 选择器的优先级排序

优先级排序从高到低:!important行内样式ID选择器类选择器

link和a标签区别

link是一个组件,用处也是页面内跳转。a是基础的标签,也是用来跳的。

什么是CSS盒模型 >>> -IE盒模型和W3C盒模型

标准模式下,一个块的宽度 = width + padding(内边距) + border(边框) + margin(外边距);
怪异模式下,一个块的宽度 = width + margin(外边距) (即怪异模式下,width包含了border以及padding);

div 上下居中对齐的几种方式

第一种:flex布局

1
2
3
4
5
6
.parent {
display: flex;
justify-content: center; // 水平居中
align-items: center; // 垂直居中
height: 100vh; // 或其他高度
}

第二种:grid网格布局

1
2
3
4
5
.parent {
display: grid;
place-items: center; // 水平和垂直都居中
height: 100vh; // 或者其他需要的高度
}

第三种:相对定位和绝对定位

1
2
3
4
5
6
7
.parent { position: relative; height: 100vh; }
.child {
position: absolute;
top: 50%;
left: 50%;
transform:translate(-50%, -50%);
}

第四种:line-height 适用于单行文本

1
2
3
4
.parent {
line-height: 100vh;
text-align: cente
}

伪类和伪元素的区别

伪类:伪类用于选择DOM树之外的信息:hover 伪类用于选择鼠标悬停在其上的元素,:visited 用于选择已访问的链接等
伪元素:伪元素为DOM树没有定义的虚拟元素。 例如,::before::after 伪元素允许在元素内容之前或之后插入内容

深拷贝与浅拷贝

浅拷贝
在栈内存中重新开辟一块内存空间,并将拷贝对象储存在栈内存中的数据存放到其中。
**存在问题:**浅拷贝只复制了引用,所以修改新对象会影响到原对象
实现方法: 使用赋值运算符(=)或者Object.assign()函数进行拷贝

深拷贝
另外创造一个一模一样的对象
**优点:**修改新对象不会影响到原对象
**实现方法:**递归拷贝 JSON.parse(JSON.stringify(obj)) …扩展运算符
const b = […a]; // 这只适用于一层深拷贝
const c = JSON.parse(JSON.stringify(a)); // 深拷贝
// 如果是个对象有函数或者空值,undefind时会有问题

1
2
3
4
5
6
7
8
9
10
11
12
13
// 对象的深拷贝
JSON.parse(JSON.stringify())
// 递归的实现复制一个对象或者数组
function clone(obj){
if(obj === null && typeof obj !=== 'object') {
return obj
}
const cloneObj= Array.isArray(obj) ? []:{}
for(const key in obj){
cloneObj[key]= clone(obj[key])
}
return cloneObj;
}

封装axios

例如一次发出两个一模一样的请求如何清除一个,通过使用 AxiosCancelToken 和请求拦截器,如果已经有相同的请求在进行中,取消之前的请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//axios封装
import axios from 'axios';
const instance = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000,
});
// 封装 GET 请求
const get = (url, params, cancelToken)=>{
return instance.get(url, {params, cancelToken })
};
// 封装 POST 请求
const post = (url, data, cancelToken)=>{
return instance.post(url, data, { cancelToken });
};
export default {get,post,};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//使用 CancelToken 取消重复请求
import axios from 'axios';
import api from './api'; // 上面封装的 Axios 实例

const pendingRequests = new Map();
const CancelToken = axios.CancelToken;

const requestInterceptor = (config) => {
const { url, method, params, data } = config;
// 生成唯一标识符
const key = `${method}-${url}-${JSON.stringify(params)}-${JSON.stringify(data)}`;
if (pendingRequests.has(key)) {
// 如果已经有相同的请求在进行中,取消之前的请求
const cancelToken = pendingRequests.get(key);
cancelToken('Request canceled due to duplicate request');
}
// 创建新的取消令牌
const source = CancelToken.source();
config.cancelToken = source.token;
// 将新的请求加入到 pendingRequests 中
pendingRequests.set(key, source.cancel);
// 在请求完成后删除该请求
config.interceptors.response.use(
(response) => {
pendingRequests.delete(key);
return response;
},
(error) => {
pendingRequests.delete(key);
return Promise.reject(error);
}
);
return config;
};

// 添加请求拦截器
instance.interceptors.request.use(requestInterceptor);

// 示例请求
const fetchUserData = async (userId) => {
try { } catch (error) {}
};

// 发起两个相同的请求
fetchUserData(1);
fetchUserData(1);

HTTPS的工作流程,HTTPS证书的验证

**客户端发起HTTPS请求:**客户端向服务器发起HTTPS请求,并指定要访问的HTTPS资源的URL。
**服务器返回公钥证书:**服务器将包含公钥的证书发送给客户端。
客户端验证证书:客户端验证证书的合法性,包括证书是否由受信任的CA(证书颁发机构)签发、证书是否过期等
**生成并发送对称加密密钥:**如果证书验证通过,客户端将生成一个对称加密密钥,并使用服务器公钥对该密钥进行加密后发送给服务器。
**服务器解密对称加密密钥:**服务器使用自己的私钥解密得到对称加密密钥。
**加密传输数据:**双方使用协商好的对称加密密钥对传输的数据进行加密和解密。

JSONP原理

利用script标签 的 src 没有跨域限制的“漏洞” 来达到与第三方通讯的目的。只能处理get请求
CORS:服务器端支持CORS主要通过设置Access-Control-Allow-Origin进行。浏览器检测到相应设置则允许Ajax跨域访问。

vue中的跨域问题:
找到配置文件config.js 修改proxyTable

1
2
3
4
5
6
7
8
9
proxyTable:
'/api': {
target: 'http://www.xxxxxx.com/api'//指定代理的地址
changeOrigin: true//是否允许跨越, 改变源到url,在虚拟主机上很有用
pathRewrite: {
'^/api': '/', // 重写
}
}
// 若后端地址不带路径’/api’, ‘http://www.xxxxxx.com/api’ 改为‘http://www.xxxxxx.com’

cookie、sessionStorage、localStorage的区别

它们的区别在于存储的有效期和作用域的不同
**cookie:**默认的,有效期很短,一旦用户关闭浏览器,Cookie保持的数据就会丢失;cookie存储空间比较小( 4KB左右)
为解决 HTTP 无状态的问题,常使用 Cookie 和 Session 等机制来在客户端和服务器之间保持状态。Cookie 是一种在客户端存储少量数据并在每个请求中发送给服务器的机制,而 Session 则是在服务器端存储用户状态信息,并通过在客户端和服务器之间传递 Session ID 来保持会话状态
localStorage:存储的数据是永久性的, 除非手动删除;存储大小通常为5-10MB;作用域限制在文档源级别,同源的文档间共享同样的localStorage数据
sessionStorage:存储的数据存在会话期 ; 通常可以达到5MB左右;一旦窗口或者浏览器标签页关闭存储的数据也会被删除; 作用域也是限定在文档源中。

浏览器与服务器的交互原理

  1. 输入网址
  2. 浏览器发送 http 请求
  3. 与dns 建立tcp/ip 3次握手
  4. 服务器 解析 并查找对应的域名
  5. 服务器相应数据返回
  6. 浏览器 下载 解析 服务器的响应数据
  7. 创建dom树 并解析css 与js 直到页面渲染完毕

A解释一下闭包,B为什么要使用闭包? 缺点

1
2
3
4
5
6
7
function a(){
var n =0;
function b(){
n++;
console.log(n);
}
}

**闭包:**以上代码中,b 函数访问了构造函数 a 里面的变量,所以形成了一个闭包
**使用闭包的原因:**想要持续的使用一个变量,放在全局中会造成全局污染,放在函数中,函数执行完后会销毁,变量也随之销毁,因此需要使用闭包。
拓展: 闭包函数是在window作用域下执行的,也就是说,this指向windows
**缺点 :**内存泄露问题, 所以不能滥用闭包

解释一下作用域链

函数A 嵌套函数B, 函数B嵌套函数C :函数C里访问一个变量,先去C的作用域找 ,再往上一级找,直到window

如何处理不让别人盗用你的图片,访问你的服务器资源?

  • 对于 nginx,可考虑用 location 通配你的图片后缀,根据 refer,再决定是否返回图片资源。
  • 又拍云、七牛云都有防盗链配置
  • 若未使用 cdn,即需要自己做防盗链。
    • 一是判断 refer,看来源是不是自己的网站,不是就拒绝。适用范围最大,也容易破解, 因为 refer 可以伪造
    • 二是 session 校验,若不通过特定服务生成 cookie 和 session 就不能请求得到资源。最保险,因为 session 在后端。
  • 给图片加水印

如何优化网站性能

  • 许多小图片整合到一张大图片中(精灵图)减少网页http请求,以提升网页加载速度。对于小图标,可使用 base64 位编码,以减少网络请求。但不建议大图使用,比较耗费CPU; 小图标优势在于:减少 HTTP 请求; 避免文件跨域; 修改及时生效
  • 代码压缩,应用第三方资源库,cdn 托管
  • 控制资源文件加载优先级,css 优先,一般情况下都是CSS在头部,JS在底部。
  • 利用浏览器缓存
  • 减少页面重排,使用CSS3代码代替JS动画(尽可能避免重绘重排以及回流);
  • 图片lazyload 懒加载,提高用户体验
  • 禁止使用gif图片实现loading效果(降低CPU消耗,提升渲染性能);
  • 减少dom 操作,优化js