写了个脚本,发现CSDN的前端居然如此不严谨
2025-06-26 09:42 阅读(29)

引言

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


然后我突然灵光一闪:


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


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

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

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

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

实现原理

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

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


我们知道,大部分网页的数据接口都是通过 XMLHttpRequest 或 fetch 发起的,而 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 博客后台为例,先找到博客数据接口



我们在 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

链接:https://juejin.cn