注册
web

写了个脚本,发现CSDN的前端居然如此不严谨

引言


最近在折腾油猴脚本开发,顺手搞了一个可以拦截任意网页接口的小工具,并修改了CSDN的博客数据接口,成功的将文章总数和展现量进行了修改。



如果你不了解什是油猴,参考这篇文章:juejin.cn/book/751468…




然后我突然灵光一闪:



既然能拦截接口、篡改数据,那我为什么不顺便测试一下 CSDN 博客在极端数据下的表现呢?



毕竟我们平时开发的时候,测试同学各种花式挑刺,什么 null、undefined、999999、-1、空数组……

每次都能把页面测出一堆边角 bug。


今天,轮到我来当一回“灵魂测试”了!

用我的脚本,造几个极限场景,看看 CSDN 的前端到底稳不稳!


实现原理


其实原理并不复杂,核心就一句话:


借助油猴的脚本注入能力 + ajax-hook 对接口请求进行拦截和修改。



我们知道,大部分网页的数据接口都是通过 XMLHttpRequestfetch 发起的,而 ajax-hook 就是一个开源的轻量工具,它能帮我们劫持原生的 XMLHttpRequest,在请求发出前、响应返回后进行自定义处理。


配合油猴脚本的注入机制,我们就可以实现在浏览器端伪造任意接口数据,用来调试前端样式、模拟数据异常、测试权限控制逻辑等等。


ajax-hook 快速上手


我们用的是 CDN 方式直接引入,简单暴力:


<script src="https://unpkg.com/ajax-hook@3.0.3/dist/ajaxhook.min.js"></script>

引入后,页面上会多出一个全局对象 ah,我们只需要调用 ah.proxy(),就可以注册一套钩子:


ah.proxy({
onRequest: (config, handler) => {
// 请求发出前
handler.next(config);
},
onError: (err, handler) => {
// 请求出错时
handler.next(err);
},
onResponse: (response, handler) => {
// 请求成功响应后
console.log("响应内容:", response.response);
handler.next(response);
}
});

拦截实现


我们以 CSDN 博客后台为例,先找到博客数据接口



地址长这样:bizapi.csdn.net/blog/phoeni…


我们在 onResponse 钩子中,加入 URL 判断,专门拦截这个接口:


onResponse: (response, handler) => {
if (response.config.url.includes("https://bizapi.csdn.net/blog/phoenix/console/v1/data/blog-statistics")) {
const hookResponse = JSON.parse(response.response);
console.log("拦截到的数据:", hookResponse);
handler.next(response);
} else {
handler.next(response);
}
}

就这样,接口拦截器初步搭建完成!


使用油猴将脚本运行在网页


接下来我们用油猴把这段脚本注入到 CSDN 博客后台页面。


// ==UserScript==
// @name CSDN博客数据接口拦截
// @namespace http://tampermonkey.net/
// @version 0.0.1
// @description 拦截接口数据,验证极端情况下的样式展示
// @author 石小石Orz
// @match https://mpbeta.csdn.net/*
// @require https://unpkg.com/ajax-hook@3.0.3/dist/ajaxhook.min.js
// @run-at document-start
// @grant none
// ==/UserScript==

(function() {
'use strict';

ah.proxy({
onRequest: (config, handler) => {
handler.next(config);
},
onError: (err, handler) => {
handler.next(err);
},
onResponse: (response, handler) => {
console.log("接口响应列表:", response);
// 这里写拦截逻辑
handler.next(response);
}
});
})();

为了测试前端的容错能力,我们可以伪造一些极端数据返回:



  • 文章总数设为 null
  • 展现量设为 0
  • 点赞数设为一个异常大的值

onResponse: (response, handler) => {
if (response.config.url.includes("https://bizapi.csdn.net/blog/phoenix/console/v1/data/blog-statistics")) {
const hookResponse = JSON.parse(response.response);

// 伪造数据
hookResponse.data[0].num = null; // 文章总数
hookResponse.data[1].num = 0; // 展现量
hookResponse.data[2].num = 99999999999999999; // 点赞数

console.log("修改后的数据:", hookResponse);

response.response = JSON.stringify(hookResponse);
}
handler.next(response);
}

结果验证


修改成功后刷新页面,可以观察到如下问题:




  • 文章总数为 null 时,布局异常,显然缺乏空值判断。
  • 点赞数为超大值 时,页面直接渲染出 100000000000000000,不仅视觉上溢出容器,连排版都崩了,前端没有做任何兼容处理。

CSDN的前端还是偷懒了呀,一点也不严谨!差评!


总结


通过这篇文章的示例,我们前端应该引以为戒,永远不要相信后端同学返回的数据,一定要做好容错处理!


通过本文,相信大家也明白了油猴脚本不仅是玩具,它在前端开发中其实是个非常实用的辅助工具!



如果你对油猴脚本的开发感兴趣,不妨看看我写的这篇教程 《油猴脚本实战指南



从小脚本写起,说不定哪天你也能靠一个脚本搞出点惊喜来!


作者:石小石Orz
来源:juejin.cn/post/7519005878566748186

0 个评论

要回复文章请先登录注册