大概总结如下:
从浏览器兼容性,代码质量,安全实践,用户体验细节等方面回答:
markdown
| 主题 | 要求/子项 | 说明/实践 |
| 跨浏览器兼容性 | 1. API兼容性 | 确保代码在不同浏览器中使用的API兼容(如事件处理、DOM操作等) |
| | 2. 避免依赖浏览器前缀 | 使用工具如 **Autoprefixer** 自动处理CSS兼容性,避免手动添加 `-webkit-` 等前缀 |
| 代码质量 | 1. 模块化与组件化 | 按功能拆分模块/组件,遵循单一职责原则(如一个函数/组件只做一件事) |
| | 2. 类型安全(TypeScript) | 使用TypeScript增强类型检查,减少运行时错误,提升代码可维护性 |
| 安全实践 | 1. XSS防护 | 对用户输入进行过滤/转义,避免直接操作`innerHTML`,使用`textContent`替代 |
| | 2. CSRF防护 | 使用CSRF Token、验证请求头(如`Origin`/`Referer`)、设置SameSite Cookie属性 |
| | 3. 防止内存泄漏 | 及时清除定时器(`setTimeout`/`setInterval`)、解绑事件监听、释放无用对象引用 |
| 用户体验细节 | 1. 防抖(Debounce) | 高频操作(如搜索输入)延迟执行,减少不必要的计算或请求 |
| | 2. 虚拟列表 | 大数据量渲染时,仅渲染可视区域内容,减少DOM节点数量以提升性能 |
| | 3. 动画性能优化 | 使用`requestAnimationFrame`、CSS3动画(`transform`/`opacity`),避免强制同步布局 |
一般正常项目交付后,会有渗透测试报告,查出来的漏洞也是我们平时开发应该注意的事项
1.内网IP信息泄露
风险:内网IP信息泄露是指内部网络中IP地址、网络拓扑结构或其他相关信息被未授权的外部人员获取的情况。这种信息泄露可能导致恶意用户在网络攻击中利用这些信息,进行网络入侵、扫描、篡改或其他形式的攻击

- 解决办法: 尽量避免硬编码内网ip在代码中
2.敏感数据暴露:明文传输密码、未加密存储用户隐私数据
风险:泄露用户相关隐私等等
解决办法:敏感数据采用加密后传输
以下为请求接口时加密参数的伪代码
js
const apiEncrypt = ()=>{
...
const decryptKey = 'key1';
const dataKey = 'key2';
// 生成一个唯一id
const guidKey = guid();
const encryptData = encryptByDES(JSON.stringify(data), guidKey);
// 加密后参数
const requestData = { [`${decryptKey}`]: guidKey, [`${dataKey}`]: encodeURIComponent(encryptData) };
requestConfig.data = Qs.stringify(requestData);
return new Promise(resolve => {
request(requestConfig)
.then(result => {
...
result.value = decryptByDES(result.value, guidKey);
resolve(result);
...
})
.catch(error => {
...
});
});
}
3.加密密钥信息泄露
风险:加密密钥是确保数据安全和隐私的核心组成部分,其泄露可能导致敏感信息的被非法访问、篡改或伪造。加密密钥信息泄露漏洞通常是由于管理不当、配置错误或缺乏有效的安全措施所导致的
示例:
漏扫过程如下3步:
-
抓到信息泄露
-
抓包加密后的信息

- 进行在线解密

- 解决办法:
- 密钥存放到服务端,获取接口获取(推荐)
- 如果业务改动大或者数据安全性要求不高,增加对密钥进行二次加密
补充一下常用加密算法
- 对称加密:AES,DES 等,加解密公用同一套密钥
- 非对称加密:RSA,ECC等,使用公钥(加密)和私钥(解密)
这里推荐一种浏览器环境下加解密算法,基于window.crypto
js
// 生成密钥(保存此密钥以便后续解密)
async function generateKey() {
return window.crypto.subtle.generateKey(
{ name: "AES-GCM", length: 256 },
true, // 是否可导出
["encrypt", "decrypt"]
);
}
// 加密函数
async function encryptData(plaintext, key) {
const iv = window.crypto.getRandomValues(new Uint8Array(12)); // 初始化向量
const encoded = new TextEncoder().encode(plaintext);
const ciphertext = await window.crypto.subtle.encrypt(
{ name: "AES-GCM", iv },
key,
encoded
);
return { iv, ciphertext };
}
// 解密函数
async function decryptData(ciphertext, key, iv) {
try {
const decrypted = await window.crypto.subtle.decrypt(
{ name: "AES-GCM", iv },
key,
ciphertext
);
return new TextDecoder().decode(decrypted);
} catch (e) {
console.error("解密失败:", e);
}
}
// 使用示例
(async () => {
const key = await generateKey();
const data = "Hello, World!";
// 加密
const { iv, ciphertext } = await encryptData(data, key);
console.log("加密结果:", { iv, ciphertext });
// 解密
const decrypted = await decryptData(ciphertext, key, iv);
console.log("解密结果:", decrypted);
})();
4.apache license信息泄露
风险:Apache License 是一个广泛使用的开源软件许可证,允许用户自由使用、修改和分发软件。但是,当与 Apache License 相关的信息泄露时,可能会导致版权和知识产权的隐患。这种信息泄露通常表现为敏感的许可证信息、项目的维护者信息或其他知识产权相关的资料被未授权访问或公开
- 解决办法:
- 关闭提取注释等到单独文件的功能
- 忽略复制public下的LICENSE文件

js
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
// ... 其他配置
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {},
// 不生成 .LICENSE.txt 文件
extractComments: false,
}),
],
},
};
// 忽略复制public下的LICENSE文件
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'public', // 复制 public 目录下的文件
to: './',
globOptions: {
ignore: ['**/LICENSE'], // 忽略 LICENSE 文件
},
},
],
}),
],
};
vue.config.js
config.optimization.minimizer('terser').tap(args => {
args[0].terserOptions.compress.drop_console = true;
args[0].extractComments = false;// 关键配置
return args;
});