2025-11-14 09:54:47
龙葵花语的核心寓意包括“沉不住气”象征冲动与不稳重,以及“执着与坚定”代表对目标、爱情和信仰的坚持,同时涵盖危险与诱惑、孤傲坚韧等多元象征。
龙葵这种植物,在自己小时候就见过,并且也吃过无数次。那时候,并不知道她的名字。直到后来玩到一款游戏《仙剑奇侠传 3》,看到里面的任务名字,龙葵,搜索了一下,才知道原来是它。
而游戏中各种人物名字,景天、雪见、长卿、重楼,也剧是药材名称。那时候才发现,自己所谓的常识是何其浅薄而又无知。
阳台上的花,花开花谢,落叶枯萎,来来回回换了无数次的花,阳台上空闲的花盆也越来越多。终于,有一天看淘宝的时候,看到了一个熟悉的身影,那就是龙葵。紫色的浆果,跟小时候看到的一模一样,只是,现在哪怕回到村里竟也不常见了。买了两包种子,回来之后收拾了一下花盆,饶有兴致的种了下去。
后来就是浇浇水,倒也不用特别的照顾。同时还买了一包蛇莓的种子,只是,这个种子自从种下去之后,就再也没见过,两个花盆里看不出有任何发芽的迹象,也找不到了那些种子。
终于某一天,自己去给从发芽的地瓜上拔下来的芽浇水的时候。看到了花盆里漏出头的龙葵,欣欣向荣,或许,她更像野草吧。
前段时间还怕没有蜜蜂授粉,龙葵没法结果。前段时间自己还用棉签尝试给花朵授粉,现在看来,似乎也没必要,哪怕没有蜜蜂授粉,现在也结满了小果子,圆圆的,绿绿的。
小的时候,这龙葵的果实,其实不单可以吃,还可以用来当玩具。夏天麦收的时候,也是龙葵大量结果的时候。这下一小段麦秆,去掉两头的关节,就剩下一条通透的小管子。
用指甲把麦秆的一头剥开成对称的十字,弯曲的时候不要太平,稍微有点幅度,把龙葵圆溜溜的果实去掉果蒂,放到那个十字口里。竖着举起来,仰起头,把麦秆的另外一头放进嘴里,向上吹气,龙葵的果子就会随着气流在麦秆的头上转动跳舞。
而至于为什么能跳舞,这个就该去问伯努利了,毕竟伯努利的流体力学方程能解答这个疑惑。
找到成熟的紫色的果子,就会摘下来吃掉。虽然小小的,但是味道真的很好。
然而,并不是所有的东西都有这种顽强的生命力,昨天的时候发现评论呢亲密度标签全部都挂了。
打开网站发现已经暂停服务了:
不是所有的服务都像自己的博客一样,有这么顽强的生命力,到目前位置已经熬死了无数的服务,好用的,不好用的,免费的,收费的。看着无数的服务倒下去。
好在这个东西是开源的,于是干脆自己又部署了一套。
昨天看到 枋柚梓 发布的 umami 升级的文章,之前的 umami 是通过 mysql 编译安装的。而现在这个新版本已经放弃了 mysql,尽管每天都看到升级提示,是在没动力去升级,每次升级编译是个问题,数据库升级也是个问题。于是放弃了所有的历史数据,干脆 docker 重新装了一个,只是换了 pg 数据库之后,确实麻烦了一些。
这几天的访问量和各种指标也的确离谱,应该还是有沙雕在陆陆续续的攻击。
尽管部署好了,但是还有一些问题没解决。现在却也不想解决了,例如那个网站图标不显示的问题。强迫症的问题,等以后哪天想处理了再处理吧,毕竟,还有一切其他的乱七八糟的事情要做。
有时候想想龙葵的花语也挺矛盾的,沉不住气,与执着。然而,这种矛盾又无比和谐,尽管沉不住气,但是却有着坚定的信仰。
挺好的,希望自己也能一直坚持下去。
2025-11-13 15:27:15
上午的时候,收到 梦不见的梦 的一条 qq 消息,说出现了授权问题。
看了下提示域名,大概率就是 tm 百度地图弹的,那个域名做了个足迹应用就这么放着。
就在上个月自己更换 ssl 证书的时候还一切正常,结果现在来了这么一出。本来就是个人开发者,纯自用的东西,还经常收到百度的电话让升级企业认证,之前就是不小心升级了,结果一年要五万的授权费用。
我 tm 就自己玩的,还需要花钱,真 tm 服了。看来这戏破玩意儿都完犊子之后,最后能玩的也就只剩下天地图了。
刚开始是以为嵌入的问题,看了下嵌入页面都会提示:
各种提示信息:
【d45a31】未获取商用授权,平台资源与服务稳定性受限;详情信息请前往:https://lbs.baidu.com/faq/search?id=314&title=908
并且后来发现,不单纯是弹窗在地图的贴图上也会出现授权提示,不得不说。这狗皮膏药贴的有水平。
对应的 js:
地址:
https://api.map.baidu.com/?qt=cen&b=7597813.822562976%2C687420.7063757228%3B15519477.822562976%2C7879996.706375723&l=5&ie=utf-8&oue=1&fromproduct=jsapi&ak=BxlnBNX55clLsUHVFZlaukyJesN5F5VI&callback=BMapGL._rd._cbk28033&v=gl&seckey=hNJCxM58roJGqVuMKRuYPEZfDZ%2FdhlL4Pp7JxBsDoLNUSc3QN6CRIbBdAJ%2FOt7zPayXwFYMsbLGx0%2BZUValnOg%3D%3D%2ChNJCxM58roJGqVuMKRuYPEZfDZ_dhlL4Pp7JxBsDoLPlabo3s2HGFnIPFXI8e1esM9-LzywgHJdkZjwHcr89ZaWfdPB6XAgd7DE4lcFgxfu8J0x_GywX0u2he7lW2roGgTrZQMyK7kcSPMHFwMyFrx45ktBewEco-xsnR-zdIctg5lIvP6h-iihbsl6ehY9AbrnGwefDt0BtO6gKCedJ8PeXNIUPh2rilmKFv6PZRd0&timeStamp=1763012808396&sign=07d57e493b29
内容:
/**/BMapGL._rd._cbk28033 && BMapGL._rd._cbk28033({"result":{"b":"7597813.822562976,687420.7063757228;15519477.822562976,7879996.706375723","callback":"BMapGL._rd._cbk28033","catalogID":0,"count":0,"current_null":1,"db":0,"error":503,"error_msg":"未获取商用授权,平台资源与服务稳定性受限;详情信息请前往:https://lbs.baidu.com/faq/search?id=314\u0026title=908","fromproduct":"jsapi","ie":"utf-8","jump_back":0,"l":"5","op_gel":0,"oue":"1","popup":1,"qt":"cen","requery":"","res_l":-1,"res_x":"0.000000","res_y":"0.000000","return_query":"","seckey":"hNJCxM58roJGqVuMKRuYPEZfDZ/dhlL4Pp7JxBsDoLNUSc3QN6CRIbBdAJ/Ot7zPayXwFYMsbLGx0+ZUValnOg==,hNJCxM58roJGqVuMKRuYPEZfDZ_dhlL4Pp7JxBsDoLPlabo3s2HGFnIPFXI8e1esM9-LzywgHJdkZjwHcr89ZaWfdPB6XAgd7DE4lcFgxfu8J0x_GywX0u2he7lW2roGgTrZQMyK7kcSPMHFwMyFrx45ktBewEco-xsnR-zdIctg5lIvP6h-iihbsl6ehY9AbrnGwefDt0BtO6gKCedJ8PeXNIUPh2rilmKFv6PZRd0","sign":"07d57e493b29","spec_dispnum":0,"time":0,"timeStamp":"1763012808396","total":0,"tp":0,"type":11,"v":"gl","wd":"","wd2":"","what":"","where":""},"current_city":{"code":0,"geo":"","level":0,"name":"","sup":0,"sup_bus":0,"sup_business_area":0,"sup_lukuang":0,"sup_subway":0,"type":0,"up_province_name":""},"hot_city":["北京市|131","上海市|289","广州市|257","深圳市|340","成都市|75","天津市|332","南京市|315","杭州市|179","武汉市|218","重庆市|132"]})
地址:
https://api.map.baidu.com/?qt=verify&v=gl&type=webgl&ak=BxlnBNX55clLsUHVFZlaukyJesN5F5VI&time=1763012794639&callback=BMapGL.bmapVerifyCbk
内容:
/**/BMapGL.bmapVerifyCbk && BMapGL.bmapVerifyCbk({"error":503,"error_msg":"未获取商用授权,平台资源与服务稳定性受限;详情信息请前往:https://lbs.baidu.com/faq/search?id=314\u0026title=908","popup":1})
我这个破玩意儿就是纯粹个玩具啊,你何苦这么狠心呢?!
对于这个东西,其实我也没啥好办法,刚开始登录百度 lbs 地图后台提示账号要年审。结果进行账号年审之后依然提示这个错误:
这尼玛就离谱了啊,既然你年审不能解决,那就直接 hook 大法:
<!-- 拦截百度地图弹窗相关请求和Hook方法 -->
<script>
(function() {
// 1. 拦截 fetch 请求
const originalFetch = window.fetch;
window.fetch = function(...args) {
const url = args[0];
if (typeof url === 'string' && url.includes('api.map.baidu.com')) {
// 检查是否是弹窗相关的请求
if (url.includes('qt=verify') || url.includes('qt=cen')) {
console.log('拦截百度地图弹窗请求:', url);
// 返回一个模拟的成功响应,避免弹窗
return Promise.resolve(new Response(JSON.stringify({
error: 0,
error_msg: "",
popup: 0,
result: {
error: 0,
popup: 0
}
}), {
status: 200,
headers: { 'Content-Type': 'application/json' }
}));
}
}
return originalFetch.apply(this, args);
};
// 2. 拦截 XMLHttpRequest
const originalXHROpen = XMLHttpRequest.prototype.open;
const originalXHRSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.open = function(method, url, ...rest) {
this._url = url;
if (typeof url === 'string' && url.includes('api.map.baidu.com')) {
if (url.includes('qt=verify') || url.includes('qt=cen')) {
console.log('拦截百度地图弹窗XHR请求:', url);
// 标记为已拦截,在send时处理
this._intercepted = true;
}
}
return originalXHROpen.apply(this, [method, url, ...rest]);
};
XMLHttpRequest.prototype.send = function(...args) {
if (this._intercepted) {
// 模拟成功响应
Object.defineProperty(this, 'status', { value: 200, writable: false });
Object.defineProperty(this, 'statusText', { value: 'OK', writable: false });
Object.defineProperty(this, 'responseText', {
value: JSON.stringify({
error: 0,
error_msg: "",
popup: 0,
result: {
error: 0,
popup: 0
}
}),
writable: false
});
Object.defineProperty(this, 'readyState', { value: 4, writable: false });
// 触发事件
if (this.onreadystatechange) {
this.onreadystatechange();
}
if (this.onload) {
this.onload();
}
return;
}
return originalXHRSend.apply(this, args);
};
// 3. 拦截 JSONP 回调(百度地图使用JSONP)
const originalCreateElement = document.createElement;
const originalAppendChild = Node.prototype.appendChild;
const originalInsertBefore = Node.prototype.insertBefore;
document.createElement = function(tagName, ...rest) {
const element = originalCreateElement.apply(this, [tagName, ...rest]);
// 处理div元素,防止创建弹窗
if (tagName.toLowerCase() === 'div') {
const originalSetAttribute = element.setAttribute;
const originalAddClass = element.classList?.add;
// Hook setAttribute,检查可能用于弹窗的属性
element.setAttribute = function(name, value) {
if (typeof value === 'string' && (
value.includes('商用授权') ||
value.includes('business_accredit') ||
value.includes('lbs.baidu.com') ||
(name === 'class' && (value.includes('dialog') || value.includes('modal') || value.includes('popup')))
)) {
console.log('拦截百度地图弹窗元素创建:', name, value);
// 不设置属性,或者设置为隐藏
if (name === 'style') {
return originalSetAttribute.call(this, name, 'display:none !important;');
}
return; // 不设置属性
}
return originalSetAttribute.apply(this, arguments);
};
// Hook classList.add
if (element.classList && originalAddClass) {
const classListAdd = element.classList.add;
element.classList.add = function(...tokens) {
for (let token of tokens) {
if (typeof token === 'string' && (
token.includes('dialog') ||
token.includes('modal') ||
token.includes('popup') ||
token.includes('alert')
)) {
console.log('拦截百度地图弹窗class添加:', token);
continue; // 跳过这个class
}
}
return classListAdd.apply(this, tokens);
};
}
// Hook appendChild,如果添加了包含授权相关文本的子元素,则隐藏
const originalDivAppendChild = element.appendChild;
element.appendChild = function(child) {
if (child && child.textContent) {
const text = child.textContent;
if (text.includes('商用授权') ||
text.includes('business_accredit') ||
text.includes('lbs.baidu.com') ||
text.includes('未完成商用授权')) {
console.log('拦截百度地图弹窗内容添加');
// 隐藏元素而不是添加
if (child.style) {
child.style.display = 'none';
}
}
}
return originalDivAppendChild.apply(this, arguments);
};
}
if (tagName.toLowerCase() === 'script') {
const originalSetAttribute = element.setAttribute;
const originalSetProperty = Object.getOwnPropertyDescriptor(HTMLScriptElement.prototype, 'src')?.set;
// Hook setAttribute
element.setAttribute = function(name, value) {
if (name === 'src' && typeof value === 'string' && value.includes('api.map.baidu.com')) {
// 拦截所有包含callback参数的JSONP请求(包括缩放等操作触发的请求)
// 只要包含callback参数就拦截,确保所有百度地图API回调都被处理
if (value.includes('callback=')) {
console.log('拦截百度地图JSONP请求 (setAttribute):', value);
value = modifyJsonpCallback(value);
}
}
return originalSetAttribute.apply(this, arguments);
};
// Hook src 属性设置
if (originalSetProperty) {
Object.defineProperty(element, 'src', {
set: function(value) {
if (typeof value === 'string' && value.includes('api.map.baidu.com')) {
// 拦截所有包含callback参数的JSONP请求
if (value.includes('callback=')) {
console.log('拦截百度地图JSONP请求 (src property):', value);
value = modifyJsonpCallback(value);
}
}
originalSetProperty.call(this, value);
},
get: function() {
return this.getAttribute('src');
},
configurable: true
});
}
// 标记这个script元素,以便在添加到DOM时检查
element._isBaiduMapScript = true;
}
return element;
};
// Hook appendChild 和 insertBefore,在添加到DOM前最后检查
Node.prototype.appendChild = function(child) {
if (child && child._isBaiduMapScript && child.src) {
// 拦截所有包含callback的百度地图请求
if (child.src.includes('api.map.baidu.com') && child.src.includes('callback=')) {
// 确保已经修改了回调
if (!child.src.includes('_baidu_map_popup_blocker_')) {
child.src = modifyJsonpCallback(child.src);
}
}
}
return originalAppendChild.apply(this, arguments);
};
Node.prototype.insertBefore = function(newNode, referenceNode) {
if (newNode && newNode._isBaiduMapScript && newNode.src) {
// 拦截所有包含callback的百度地图请求
if (newNode.src.includes('api.map.baidu.com') && newNode.src.includes('callback=')) {
// 确保已经修改了回调
if (!newNode.src.includes('_baidu_map_popup_blocker_')) {
newNode.src = modifyJsonpCallback(newNode.src);
}
}
}
return originalInsertBefore.apply(this, arguments);
};
// 修改JSONP回调的辅助函数
function modifyJsonpCallback(url) {
// 匹配 callback=xxx 或 callback=xxx.xxx.xxx 格式
return url.replace(
/callback=([^&]+)/,
(match, callbackName) => {
// 创建一个包装函数,修改返回数据
const wrapperName = '_baidu_map_popup_blocker_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
const callbackPath = callbackName.split('.');
// 创建包装回调函数
window[wrapperName] = function(data) {
// 深度修改所有可能的弹窗相关字段
function removePopupFields(obj) {
if (!obj || typeof obj !== 'object') return;
// 修改当前对象的字段
if (obj.popup !== undefined) {
obj.popup = 0;
}
if (obj.error !== undefined && obj.error === 503) {
obj.error = 0;
obj.error_msg = "";
}
// 递归处理嵌套对象
for (let key in obj) {
if (obj.hasOwnProperty(key) && typeof obj[key] === 'object') {
removePopupFields(obj[key]);
}
}
}
if (data && typeof data === 'object') {
removePopupFields(data);
}
// 调用原始回调
let callback = window;
for (let i = 0; i < callbackPath.length; i++) {
if (callback && callback[callbackPath[i]]) {
callback = callback[callbackPath[i]];
} else {
callback = null;
break;
}
}
if (callback && typeof callback === 'function') {
try {
callback(data);
} catch(e) {
console.error('Error calling original callback:', e);
}
}
// 延迟清理包装函数,确保回调已执行
setTimeout(function() {
try {
delete window[wrapperName];
} catch(e) {}
}, 1000);
};
return 'callback=' + wrapperName;
}
);
}
// 4. Hook BMapGL 相关方法(如果已经加载)
function hookBMapGLMethods() {
if (window.BMapGL) {
// Hook bmapVerifyCbk 回调
if (window.BMapGL.bmapVerifyCbk) {
const originalVerifyCbk = window.BMapGL.bmapVerifyCbk;
// 深度修改弹窗字段的辅助函数
function removePopupFieldsDeepVerify(obj) {
if (!obj || typeof obj !== 'object') return;
if (obj.popup !== undefined) obj.popup = 0;
if (obj.error !== undefined && obj.error === 503) {
obj.error = 0;
obj.error_msg = "";
}
for (let key in obj) {
if (obj.hasOwnProperty(key) && typeof obj[key] === 'object' && obj[key] !== null) {
removePopupFieldsDeepVerify(obj[key]);
}
}
}
window.BMapGL.bmapVerifyCbk = function(data) {
if (data && typeof data === 'object') {
removePopupFieldsDeepVerify(data);
}
return originalVerifyCbk ? originalVerifyCbk.call(this, data) : undefined;
};
}
// Hook 动态回调(如 _rd._cbk28033)
if (window.BMapGL._rd) {
const originalRd = window.BMapGL._rd;
// Hook _cbk 方法(用于创建动态回调)
if (originalRd._cbk) {
const originalCbk = originalRd._cbk;
// 深度修改弹窗字段的辅助函数(局部定义)
function removePopupFieldsDeepLocal(obj) {
if (!obj || typeof obj !== 'object') return;
if (obj.popup !== undefined) obj.popup = 0;
if (obj.error !== undefined && obj.error === 503) {
obj.error = 0;
obj.error_msg = "";
}
for (let key in obj) {
if (obj.hasOwnProperty(key) && typeof obj[key] === 'object' && obj[key] !== null) {
removePopupFieldsDeepLocal(obj[key]);
}
}
}
originalRd._cbk = function(callbackName) {
const originalCallback = originalCbk.call(this, callbackName);
if (typeof originalCallback === 'function') {
return function(data) {
if (data && typeof data === 'object') {
removePopupFieldsDeepLocal(data);
}
return originalCallback.call(this, data);
};
}
return originalCallback;
};
}
// 使用 Proxy 拦截所有动态创建的回调属性
try {
// 深度修改弹窗字段的辅助函数(用于Proxy)
function removePopupFieldsDeepProxy(obj) {
if (!obj || typeof obj !== 'object') return;
if (obj.popup !== undefined) obj.popup = 0;
if (obj.error !== undefined && obj.error === 503) {
obj.error = 0;
obj.error_msg = "";
}
for (let key in obj) {
if (obj.hasOwnProperty(key) && typeof obj[key] === 'object' && obj[key] !== null) {
removePopupFieldsDeepProxy(obj[key]);
}
}
}
const rdProxy = new Proxy(originalRd, {
set: function(target, prop, value) {
if (typeof prop === 'string' && prop.startsWith('_cbk') && typeof value === 'function') {
// 包装回调函数
target[prop] = function(data) {
if (data && typeof data === 'object') {
removePopupFieldsDeepProxy(data);
}
return value.call(this, data);
};
return true;
}
target[prop] = value;
return true;
}
});
window.BMapGL._rd = rdProxy;
} catch(e) {
console.log('Proxy not supported, using fallback method');
}
}
// 深度修改弹窗字段的辅助函数
function removePopupFieldsDeep(obj) {
if (!obj || typeof obj !== 'object') return;
// 修改当前对象的字段
if (obj.popup !== undefined) {
obj.popup = 0;
}
if (obj.error !== undefined && obj.error === 503) {
obj.error = 0;
obj.error_msg = "";
}
// 递归处理嵌套对象
for (let key in obj) {
if (obj.hasOwnProperty(key) && typeof obj[key] === 'object' && obj[key] !== null) {
removePopupFieldsDeep(obj[key]);
}
}
}
// 定期检查并Hook新创建的回调函数
const callbackMonitor = setInterval(function() {
if (window.BMapGL && window.BMapGL._rd) {
// 检查所有以_cbk开头的属性
for (let key in window.BMapGL._rd) {
if (key.startsWith('_cbk') && typeof window.BMapGL._rd[key] === 'function') {
const originalCbk = window.BMapGL._rd[key];
// 如果还没有被Hook过
if (!originalCbk._hooked) {
window.BMapGL._rd[key] = function(data) {
if (data && typeof data === 'object') {
removePopupFieldsDeep(data);
}
return originalCbk.call(this, data);
};
window.BMapGL._rd[key]._hooked = true;
console.log('Hook BMapGL callback:', key);
}
}
}
}
// 也检查BMapGL上的其他回调
if (window.BMapGL) {
for (let key in window.BMapGL) {
if ((key.includes('cbk') || key.includes('Cbk') || key.includes('callback') || key.includes('Callback'))
&& typeof window.BMapGL[key] === 'function' && !window.BMapGL[key]._hooked) {
const originalCbk = window.BMapGL[key];
window.BMapGL[key] = function(data) {
if (data && typeof data === 'object') {
removePopupFieldsDeep(data);
}
return originalCbk.call(this, data);
};
window.BMapGL[key]._hooked = true;
console.log('Hook BMapGL callback:', key);
}
}
}
}, 100); // 更频繁的检查(100ms)
// 30秒后停止监控(给足够时间处理所有回调)
setTimeout(function() {
clearInterval(callbackMonitor);
}, 30000);
}
}
// 5. 监听百度地图API加载完成
const checkInterval = setInterval(function() {
if (window.BMapGL) {
hookBMapGLMethods();
clearInterval(checkInterval);
}
}, 100);
// 6. 全局拦截弹窗显示方法
// 拦截 alert
const originalAlert = window.alert;
window.alert = function(message) {
if (typeof message === 'string' && (
message.includes('商用授权') ||
message.includes('lbs.baidu.com') ||
message.includes('business_accredit') ||
message.includes('未完成商用授权')
)) {
console.log('拦截百度地图授权弹窗 (alert):', message);
return;
}
return originalAlert.apply(this, arguments);
};
// 拦截 confirm
const originalConfirm = window.confirm;
window.confirm = function(message) {
if (typeof message === 'string' && (
message.includes('商用授权') ||
message.includes('lbs.baidu.com') ||
message.includes('business_accredit') ||
message.includes('未完成商用授权')
)) {
console.log('拦截百度地图授权弹窗 (confirm):', message);
return true; // 返回true避免阻塞
}
return originalConfirm.apply(this, arguments);
};
// 拦截 prompt
const originalPrompt = window.prompt;
window.prompt = function(message, defaultText) {
if (typeof message === 'string' && (
message.includes('商用授权') ||
message.includes('lbs.baidu.com') ||
message.includes('business_accredit')
)) {
console.log('拦截百度地图授权弹窗 (prompt):', message);
return null;
}
return originalPrompt.apply(this, arguments);
};
// 7. 拦截可能用于显示弹窗的方法
window.addEventListener('load', function() {
// 拦截可能用于显示弹窗的全局函数
const popupKeywords = ['商用授权', 'business_accredit', 'lbs.baidu.com', '未完成商用授权'];
// 监控DOM变化,移除包含授权相关文本的元素
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
mutation.addedNodes.forEach(function(node) {
if (node.nodeType === 1) { // Element node
const text = node.textContent || '';
const className = node.className || '';
const id = node.id || '';
// 检查是否包含授权相关文本
if (popupKeywords.some(keyword =>
text.includes(keyword) ||
className.includes(keyword) ||
id.includes(keyword)
)) {
console.log('检测到百度地图弹窗元素,正在移除:', node);
// 立即移除或隐藏
if (node.parentNode) {
node.style.display = 'none';
// 延迟移除,避免影响其他功能
setTimeout(function() {
if (node.parentNode) {
node.parentNode.removeChild(node);
}
}, 100);
}
}
}
});
});
});
// 开始观察DOM变化
observer.observe(document.body, {
childList: true,
subtree: true
});
// 定期检查并移除弹窗元素
const popupChecker = setInterval(function() {
const allElements = document.querySelectorAll('*');
allElements.forEach(function(el) {
const text = el.textContent || '';
const className = el.className || '';
const id = el.id || '';
const style = window.getComputedStyle(el);
// 检查是否是可见的弹窗元素
if (popupKeywords.some(keyword =>
(text.includes(keyword) || className.includes(keyword) || id.includes(keyword)) &&
style.display !== 'none' &&
(style.position === 'fixed' || style.position === 'absolute') &&
(parseInt(style.zIndex) > 1000 || style.zIndex === 'auto')
)) {
console.log('检测到百度地图弹窗,正在移除:', el);
el.style.display = 'none';
setTimeout(function() {
if (el.parentNode) {
el.parentNode.removeChild(el);
}
}, 100);
}
});
}, 500);
// 30秒后停止检查
setTimeout(function() {
clearInterval(popupChecker);
}, 30000);
});
})();
</script>
实际效果:
不过既然是 hook,存在一定的稳定性问题,有可能会失效。
等哪天彻底被恶心够了,就直接换地图 sdk 了!
2025-11-12 14:02:44
这几天不知道是发生什么事了,说是不知道什么事情,但是大概率是被打了。只是这次打的挺高级的,外层的 eo 貌似也没什么反应。只是那个访问量通过 umami 看,直接爆炸了。
平常几百的访问量,昨天的时候,结果到了 2000 多,当然这不是最奇怪的,奇怪的是服务器过了会儿卡死了。之前都是因为请求太多 php-fpm 耗尽 cpu 资源卡死了,这次以为还是同样的问题。然而,并不是,发现 mysql 把 cpu 跑满了,查看日志的时候发现大量的 wp-cron.php 的请求,这尼玛,请求直接透传过来了。
另外还有一大堆 bot 的请求,包括 bing 以及一些乱起八糟的爬虫遍历。
最开始没想到什么好办法,简单粗暴的把 wp-cron.php 改名了,暂时解决了这个问题。
不过这个方法的确是高明,带着参数透传过来,wp 就是疯狂的执行,一条没执行完就到了下一条。然而,对于这种事情直接改名的确是可以解决办法,不过后来想了一下还是直接从 eo 下手吧。
尽管 eo 防住了 22 万次的攻击,但是,这些透传的请求,直接让 mysql 耗尽了 cpu 资源,也是个不错的办法,甚至请求频率都不用太高。流量到了 144g,这也不知道是哪个哥们又闲的蛋疼了,如果真的蛋疼来找姐姐啊,姐姐帮你治疗,直接给你割下来,塞你自己嘴里!
昨天晚上发现这个情况的时候,本来是想去处理下的,结果对象在用电脑,自己又不想去开笔记本,就用手机处理了一下,简单的改下了文件名。
今天早上才处理了一下,加到了 eo 的访问规则里:
尽管如此,还是对这几天的访问记录比较好奇,想看看请求了多少次。去拉 nginx 日志的时候发现文件已经 1.5G 了。直接截取这几天的记录,用 goaccess 跑了一下,但是比较奇怪的是这个 wp-cron.php 的请求竟然没有。
暂时放弃 goaccess 直接使用 ngxtop 进行数据分析:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
使用ngxtop分析Nginx日志中的POST请求
提供交互式菜单和多种分析选项
"""
import subprocess
import sys
import os
from pathlib import Path
def run_ngxtop(cmd_args):
"""运行ngxtop命令"""
venv_python = Path(__file__).parent / "venv" / "bin" / "python"
ngxtop_script = Path(__file__).parent / "venv" / "bin" / "ngxtop"
if not ngxtop_script.exists():
print("错误: ngxtop未安装,请先运行: source venv/bin/activate && pip install ngxtop")
sys.exit(1)
try:
result = subprocess.run(
[str(ngxtop_script)] + cmd_args,
capture_output=True,
text=True,
check=False
)
print(result.stdout)
if result.stderr and "error" in result.stderr.lower():
print(result.stderr, file=sys.stderr)
return result.returncode == 0
except Exception as e:
print(f"错误: {e}", file=sys.stderr)
return False
def show_menu():
"""显示菜单"""
print("\n" + "="*60)
print("Nginx日志POST请求分析 - ngxtop工具")
print("="*60)
print("1. POST请求总览")
print("2. 按URL统计POST请求 (Top 20)")
print("3. 按IP统计POST请求 (Top 20)")
print("4. 按状态码统计POST请求")
print("5. POST请求中状态码为404的URL")
print("6. POST请求中状态码为200的URL")
print("7. 可疑POST请求 (xmlrpc, wp-login等)")
print("8. POST请求详情示例")
print("9. 自定义查询")
print("0. 退出")
print("="*60)
def analyze_post_requests(log_file):
"""分析POST请求"""
if not os.path.exists(log_file):
print(f"错误: 日志文件 {log_file} 不存在")
return
base_args = ["-l", log_file, "--no-follow", "-i", 'request.startswith("POST")']
while True:
show_menu()
choice = input("\n请选择分析选项 (0-9): ").strip()
if choice == "0":
print("退出分析")
break
elif choice == "1":
print("\n【POST请求总览】")
print("-" * 60)
run_ngxtop(base_args + ["--limit", "0"])
elif choice == "2":
print("\n【按URL统计POST请求 (Top 20)】")
print("-" * 60)
run_ngxtop(base_args + ["--group-by", "request_path", "--limit", "20"])
elif choice == "3":
print("\n【按IP统计POST请求 (Top 20)】")
print("-" * 60)
run_ngxtop(base_args + ["--group-by", "remote_addr", "--limit", "20"])
elif choice == "4":
print("\n【按状态码统计POST请求】")
print("-" * 60)
run_ngxtop(base_args + ["--group-by", "status", "--limit", "0"])
elif choice == "5":
print("\n【POST请求中状态码为404的URL (Top 10)】")
print("-" * 60)
run_ngxtop(["-l", log_file, "--no-follow",
"-i", 'request.startswith("POST") and status == 404',
"--group-by", "request_path", "--limit", "10"])
elif choice == "6":
print("\n【POST请求中状态码为200的URL (Top 10)】")
print("-" * 60)
run_ngxtop(["-l", log_file, "--no-follow",
"-i", 'request.startswith("POST") and status == 200',
"--group-by", "request_path", "--limit", "10"])
elif choice == "7":
print("\n【可疑POST请求统计】")
print("-" * 60)
run_ngxtop(["-l", log_file, "--no-follow",
"-i", 'request.startswith("POST") and (request_path == "/xmlrpc.php" or request_path == "/wp-login.php" or request_path.startswith("/wp-admin"))',
"--group-by", "request_path", "--limit", "0"])
elif choice == "8":
print("\n【POST请求详情示例 (前10条)】")
print("-" * 60)
run_ngxtop(base_args + ["print", "remote_addr", "time_local", "request", "status", "bytes_sent", "--limit", "10"])
elif choice == "9":
print("\n【自定义查询】")
print("-" * 60)
print("示例查询:")
print(" - 查看特定URL: ngxtop -l <file> -i 'request.startswith(\"POST\") and request_path == \"/wp-cron.php\"'")
print(" - 查看特定IP: ngxtop -l <file> -i 'request.startswith(\"POST\") and remote_addr == \"114.66.247.160\"'")
print(" - 查看错误请求: ngxtop -l <file> -i 'request.startswith(\"POST\") and status >= 400'")
print("\n请输入自定义ngxtop命令参数 (用空格分隔):")
custom_args = input("> ").strip().split()
if custom_args:
run_ngxtop(["-l", log_file, "--no-follow"] + custom_args)
else:
print("无效的选择,请重试")
input("\n按回车键继续...")
def main():
"""主函数"""
if len(sys.argv) < 2:
# 查找默认日志文件
log_files = list(Path(".").glob("*.txt"))
if log_files:
default_log = str(log_files[0])
print(f"未指定日志文件,使用默认: {default_log}")
log_file = default_log
else:
print("用法: python analyze_with_ngxtop.py <日志文件路径>")
print("示例: python analyze_with_ngxtop.py 11-08_org.txt")
sys.exit(1)
else:
log_file = sys.argv[1]
analyze_post_requests(log_file)
if __name__ == "__main__":
main()
运行命令:
python3 analyze_with_ngxtop.py 11-08_org.txt
分析结果:
【按URL统计POST请求 (Top 20)】 ------------------------------------------------------------ running for 7 seconds, 23670 records processed: 3508.50 req/sec Summary: | count | avg_bytes_sent | 2xx | 3xx | 4xx | 5xx | |---------+------------------+-------+-------+-------+-------| | 23670 | 2381.924 | 4678 | 21 | 18574 | 397 | Detailed: | request_path | count | avg_bytes_sent | 2xx | 3xx | 4xx | 5xx | |---------------------------------+---------+------------------+-------+-------+-------+-------| | /wp-cron.php | 16454 | 731.309 | 3413 | 0 | 13034 | 7 | | /xmlrpc.php | 3102 | 416.754 | 248 | 0 | 2853 | 1 | | /wp-login.php | 2519 | 15204.250 | 0 | 0 | 2519 | 0 | | /wp-admin/admin-ajax.php | 1017 | 542.043 | 971 | 0 | 44 | 2 | | /wp-comments-post.php | 401 | 2551.357 | 0 | 14 | 0 | 387 | | /xmrpc.php | 41 | 915.000 | 0 | 0 | 41 | 0 | | /tslogin | 20 | 30543.150 | 16 | 4 | 0 | 0 | | /alfacgiapi/perl.alfa | 11 | 51292.455 | 0 | 0 | 11 | 0 | | /ALFA_DATA/alfacgiapi/perl.alfa | 11 | 51323.636 | 0 | 0 | 11 | 0 | | /index.php | 10 | 34570.900 | 10 | 0 | 0 | 0 | | /wp-plain.php | 9 | 1331.000 | 0 | 0 | 9 | 0 | | / | 9 | 28609.556 | 7 | 0 | 2 | 0 | | | 8 | 415.000 | 8 | 0 | 0 | 0 | | /flow.php | 7 | 915.000 | 0 | 0 | 7 | 0 | | /wp-admin/async-upload.php | 5 | 736.000 | 5 | 0 | 0 | 0 | | /php-cgi/php-cgi.exe | 4 | 33911.500 | 0 | 0 | 4 | 0 | | /graphql | 4 | 33469.750 | 0 | 0 | 4 | 0 | | /wp-admin/post.php | 3 | 5.000 | 0 | 3 | 0 | 0 | | /member/success.aspx | 2 | 16784.500 | 0 | 0 | 2 | 0 | | /e/aspx/upload.aspx | 2 | 16628.500 | 0 | 0 | 2 | 0 | 【按IP统计POST请求 (Top 20)】 ------------------------------------------------------------ running for 7 seconds, 23670 records processed: 3586.40 req/sec Summary: | count | avg_bytes_sent | 2xx | 3xx | 4xx | 5xx | |---------+------------------+-------+-------+-------+-------| | 23670 | 2381.924 | 4678 | 21 | 18574 | 397 | Detailed: | remote_addr | count | avg_bytes_sent | 2xx | 3xx | 4xx | 5xx | |----------------+---------+------------------+-------+-------+-------+-------| | 221.204.26.162 | 4407 | 696.960 | 1125 | 1 | 3279 | 2 | | 221.204.26.233 | 4291 | 738.947 | 1054 | 1 | 3235 | 1 | | 101.71.101.44 | 3168 | 686.088 | 911 | 4 | 2252 | 1 | | 101.71.101.106 | 2564 | 868.693 | 183 | 2 | 2379 | 0 | | 43.174.53.229 | 2094 | 7795.611 | 6 | 0 | 2088 | 0 | | 43.174.53.236 | 2090 | 7811.496 | 4 | 0 | 2086 | 0 | | 114.66.247.160 | 1810 | 743.818 | 520 | 1 | 1288 | 1 | | 114.66.246.149 | 1123 | 507.375 | 538 | 1 | 582 | 2 | | 101.71.105.47 | 104 | 574.404 | 57 | 0 | 47 | 0 | | 43.175.19.192 | 29 | 5430.241 | 1 | 0 | 15 | 13 | | 43.175.17.169 | 26 | 2520.500 | 0 | 0 | 8 | 18 | | 43.175.18.81 | 25 | 2049.720 | 1 | 0 | 6 | 18 | | 43.175.18.253 | 25 | 1835.800 | 1 | 0 | 8 | 16 | | 43.175.18.195 | 25 | 5997.720 | 0 | 0 | 8 | 17 | | 43.175.18.137 | 25 | 2101.840 | 1 | 0 | 5 | 19 | | 43.175.17.87 | 24 | 2210.208 | 0 | 0 | 5 | 19 | | 43.175.17.47 | 23 | 7488.043 | 0 | 0 | 9 | 14 | | 43.175.18.51 | 22 | 3213.455 | 0 | 0 | 8 | 14 | | 43.175.17.205 | 21 | 7011.381 | 1 | 0 | 10 | 10 | | 43.175.169.137 | 16 | 1386.562 | 3 | 0 | 6 | 7 |
而至于这些 IP 地址,多数都是国内的,这个倒是也在意料之内,毕竟国外的被拦截的概率会更高一些。
然而,goaccess 就无法分析吗?也可以,添加忽略请求参数的参数就可以了:
#!/bin/bash
# 使用goaccess的--no-query-string参数移除查询参数
# 不需要修改日志文件!
LOG_FILE="${1:-11-08_org.txt}"
OUTPUT_FILE="${2:-goaccess_no_query_report.html}"
if [ ! -f "$LOG_FILE" ]; then
echo "错误: 日志文件 $LOG_FILE 不存在"
exit 1
fi
echo "=========================================="
echo "使用GoAccess分析(移除查询参数)"
echo "=========================================="
echo "日志文件: $LOG_FILE"
echo "输出文件: $OUTPUT_FILE"
echo ""
echo "使用参数: --no-query-string (或 -q)"
echo "这将移除URL中的查询参数,只保留路径"
echo ""
# 使用--no-query-string参数
goaccess "$LOG_FILE" \
--log-format='%h %^[%d:%t %^] "%r" %s %b "%R" "%u"' \
--date-format='%d/%m/%Y' \
--time-format='%H:%M:%S' \
--no-query-string \
-o "$OUTPUT_FILE"
if [ $? -eq 0 ]; then
echo ""
echo "
报告生成成功: $OUTPUT_FILE"
echo ""
echo "现在wp-cron.php应该能正确合并统计了!"
echo ""
echo "在浏览器中打开报告查看:"
echo " open $OUTPUT_FILE # macOS"
echo " xdg-open $OUTPUT_FILE # Linux"
echo ""
echo "在交互界面中使用:"
echo " goaccess $LOG_FILE \\"
echo " --log-format='%h %^[%d:%t %^] \"%r\" %s %b \"%R\" \"%u\"' \\"
echo " --date-format='%d/%m/%Y' \\"
echo " --time-format='%H:%M:%S' \\"
echo " --no-query-string"
else
echo "
报告生成失败"
exit 1
fi
主要就是:–no-query-string参数。
实际效果:
文件没改名之前:
文件改名之后:
虽然加起来之后不到两万次,但是却让 mysql 把 cpu 资源耗尽了,这的确不失为一个低成本的攻击方式。
爬虫占比:
这几天也不知道爬虫是发什么疯
今天的访问量:
百度的统计:
咱就是说,有点时间干点正事不好吗?真是闲的。
2025-11-11 17:18:54
已经记不清楚入冬多长时间了,只是隐约记得冬天的节气一个接一个,似乎依然过了好几个了。
这气温也跟着起起起伏伏,从前天开始,暖气片竟然有一些温度了,不在那么冰冷。或许这冬天真的是来了,不过自己的体温似乎一点变化都没有,不管冷还是热,在这个冬天始终稳定在一个冰凉的状态,多少次想找个体温枪量一下自己脚的温度,却总是上床之后才想起来,又不想在去找体温枪。如果量一下的话应该是显示个 low 吧。
前段时间去拍的照片,依然有段时间了。百度网盘没有vip,所以下载照片基本都是挂在群晖的自动同步上下载。尽管速度只有 100k 左右,但是只要时间够长通知能下载完的,自动同步的好处是不用管到底下载到什么进度了。然而,想着看下下载的照片,当把内网的端口映射出来之后,各种扫描接踵而至,如逐臭的苍蝇一般,让人不胜其烦。
仅仅开了不到一天的时间就如此,这扫描也是无缝不入。虽然群晖自带防火墙,但是每次添加规则只能添加 15 个。这逻辑也是服了。 为了屏蔽国外的这些扫描器,只好添加一堆规则:
只是,这一系列昨晚之后。总觉得还是少了点东西,看了下系统上的年假还有四五天。这四五天年假,等过了元旦也就过期了。既然不能折现,何不浪费了他。
打定了主意,这大好的时光自然也不该浪费。尽管依然是冬天,但是树上的叶子依然是深绿色,枫树、银杏却早已变得火红或者金黄,尽情的飘散在这初冬之中。曾想着,等哪天下雪之后,穿一袭红色长裙站在皑皑白雪中,享受那种冰冷的热烈。
青岛的冬天,却不常见到雪,更不曾留住雪。一切都有些可遇不可求,现在的时光却是刚刚好,又怎堪辜负这大好的时光。
选了几套衣服,摄影师表示那件红的有点太突出了,可以拍个圣诞神马的。最终换了一条粉色的长裙,而至于拍摄的地点,原本是想去世博园的,摄影师却说之前去的时候,拍摄的姐妹,穿了件轻婚纱,在入口被拦住了不让进。现在这好景致,市南的公园,以及红岛的万亩枫林看比人发的都挺好看的,然而问题是太远了。尤其是从近城阳的地方开车过去也是比较费时间的,最后选择了世纪公园。
找个停车场停好车,步行到公园门口。门口一撮撮的大爷凑到一起,有的在下棋,有的在打扑克。这样的老年生活也挺好的,轻松自由。不过既然是拍照,那自然选几个场地就可以啦。
就在入口处转了转,拍了几套。这身打扮在这个季节还算是比较正常的。
等换上那条粉色的长裙之后,事情就变得没那么简单了,毕竟在这个季节还穿裙子的也的确是少数。补妆的时候,一只蚊子落在了胳膊上,化妆师小姐姐,眼疾手快直接给拍死了。没想到,冬天还有蚊子,蚊子也没想到,冬天还有穿的这么干净的,漏一大片的。
除了拍照也的确没有这种穿搭了,尽管在一周之前还看到不少拍婚纱照的,可能与工作日也有关系,可能也许是公园太偏僻,并没看到太多专程来拍照的。
直到看到这拍完的成片才发现,左下角那个姐妹的包包也入镜了。
拍照的时候,她就一直蹲在那个包包的旁边。过了几分钟,可能觉得无聊了,从包里拿出一包烟来,抽出来一只点上,抽了一口之后,就把烟夹在手指上,继续蹲那里看手机。拍照的时候,也不断的有人过来,可能都觉得这是个拍照的好地方吧。
等排到后面人越来越多了,再也没有多少空闲的地方。之前还想着往里走走,只是拍了一段时间,去湖边又拍了几站过之后却不想往里走了。总觉得有无数的好风光,但是这好风光却难以揽入怀中,毕竟时间终是有限,抱着这长裙在公园里面走也确实是有些累。
化妆的小姐姐说,裙子从后面已经扎到最紧了。感觉还是有点往下掉,有点走光。
减肥的事情依然在继续,这漫长的一个月有没有太大的进展。前天晚上,一边看《唐朝诡事录》一遍跳绳,一集电视剧看完,刚好跳了7000 多个。
昨天晚上想继续跳的时候,发身身体有点沉,跳不大动的样子,就跳了 2000 个就结束了。
状态不好的时候,真的跳不动。有的时候,挺想坚持一件事情,只是,稍微懈怠,这件事情就那么不了了之。再也没了后续,这坚持,又能坚持多久。
偶尔从镜子里看到自己,感觉似乎没那么老,但是,通过相机那高清的照片,看到自己的脸的时候,那种苍老感,却再也遮挡不住了。或许真的垂垂老矣。年龄这个东西,就这么一步步的赶尽杀绝,也不给任何喘息的机会。
的确是很多事情,再不做,可能就真的做不了了,在等待的时候,太多的事情拖到了终点,甚至是无疾而终。
多年以后,自己依然叛逆,那种自私而又无所畏惧的性格,或许,永远都不会变吧。
做的太多的事情,总是在补偿自己的童年,少年,年轻的时候那些所谓的爱而不得。
终于,现在能有能力补偿那个孩子的时候,有的时候又觉得太过于奢侈,或者不该去浪费。那种矛盾从来都没解决过,那种不了了之之后的失望更让人后悔。
不过是最终下定了决心:
我讨厌等待,我更讨厌爱而不得!
2025-11-06 20:57:13
生命,一次又一次轻薄过。
轻狂不知疲倦。
–题记
一
我听见回声,来自山谷和心间。
以寂寞的镰刀收割空旷的灵魂。
不断地重复决绝,又重复幸福。
终有绿洲摇曳在沙漠。
我相信自己。
生来如同璀璨的夏日之花。
不凋不败,妖治如火。
承受心跳的负荷和呼吸的累赘。
乐此不疲。
二
我听见音乐,来自月光和胴体。
辅极端的诱饵捕获飘渺的唯美。
一生充盈着激烈,又充盈着纯然。
总有回忆贯穿于世间。
我相信自己。
死时如同静美的秋日落叶。
不盛不乱,姿态如烟。
即便枯萎也保留丰肌清骨的傲然。
玄之又玄。
三
我听见爱情,我相信爱情。
爱情是一潭挣扎的蓝藻。
如同一阵凄微的风。
穿过我失血的静脉。
驻守岁月的信念。
四
我相信一切能够听见。
甚至预见离散,遇见另一个自己。
而有些瞬间无法把握。
任凭东走西顾,逝去的必然不返。
请看我头置簪花,一路走来一路盛开。
频频遗漏一些,又深陷风霜雨雪的感动。
五
般若波罗蜜,一声一声。
生如夏花,死如秋叶。
还在乎拥有什么。
2025-11-06 17:04:22
昨天晚上,睡觉之前,我在刷短视频。对象拿了个红色的本子过来。我问她,干嘛呢?
“算账啊”她回到。
我从床上爬下来,去电脑桌上拿另外一个手机,所有的银行 app 都是在那个手机上登录的。
打开两个 app,兴业银行和建设银行,现在建行的卡上已然没多少钱了。我把银行卡上的数额报了一下,再加上余额宝的 8 千块钱。
看她在本子上潦草的写了三行,一脸吃惊的停下来问了一句:“没了?”
“没了”,我答道。
“就这么点,每年那么多钱,怎么就没了,这几年就剩了这么点钱?”她继续追问。
我不知道该怎么回答,就这么沉默着。
“以前,我没用你的亲情卡,都是我自己出的钱。我卡上也没多少钱,很长一段时间,卡上都不到两万块钱……”她继续说道。
看我继续沉默没说话,她也停顿了一会儿。过了会儿说道:“宝子卡上的 11 万也是你的,这么一看心里多少还能欣慰一点”
在这之后又是一阵沉默,我漫无目的的划着手机,上面写的什么自己也没看清楚,也看不清楚。
“这一堆电子产品太费钱了,以后你买超过 1000 的东西跟我商量一下”她指着电脑桌那边说道。
“你去买车,你都没跟我说一声就去买了,如果有 100 万你是不是要去买 50 万的车?”她继续追问。
本来我是想解释下自己的想法的,但是话到嘴边最终还是没开口。
以前,总觉得自己是那种所谓的主角,即使不是主角,好歹也是个配角。然而,自始至终从来都不存在什么主角配角。出生的时候,靠着在小学的所谓的成绩,觉得还算是可以,以后最起码怎么也能混出点名堂来。
然而不管是意外还是生活,在上高中的时候,一切都变得那么不堪。都说穷人的孩子早当家,然而,那个当家,并不是所谓的当家,不过是早吃苦而已。而一旦开始之后,后面就是无尽的苦,没有尽头。
毕业步入社会之后,这小卒子终于过河了。似乎是走在了时代的前面,大学毕业,985 211 大学的毕业生,似乎比很多的起点高了很多。然而,那些不过是假象而已,这个卒子只不过是排兵布阵放到了前面,每一步的行进都那么简单。甚至连退路都没有,前面是什么自己却又一无所知,就这么懵懵懂懂跌跌撞撞的往前走。
以前真的是穷怕了,那种没有安全感的生活,在心里刻下了长长的印记。直到现在都是如此,高中的时候回家的客车票是 8 块钱。为了休息的时候能回家,自己要再省出 8 块钱。就怕自己坐过站或者做错了车,再也到不了。
没有安全感的孩子就是这样,害怕没有备用方案,害怕真的会出错了,万劫不复,太多而时候所谓的选择不是选择,不过是一个个的抉择,选错了这辈子真的就错了,那有什么所谓的选择,不过是在生活逼迫下一次次被逼无奈的抉择而已。
而至于买车这件事情,哪怕真的有 100 万,也不大可能去买 50 万的车。小农思想,让我去追求那种所谓的极致的性价比。至于喜欢吗?喜欢,真的是最喜欢的吗?
喜欢的东西多了,不过那都是遥远不可及的白月光。从来不属于自己,又哪里高攀的起。至于魄力,我这人没什么魄力,自然也成不了什么大事。就想那随波逐流的浮萍,随波逐流半点不由人。
太多的小卒,依然成了炮灰,这站在前线的人肉盾牌,有这么扛得住时代的洪流。而至于实现阶级跨越,那就跟不现实了。
“当然,这么多年了买辆车也不是不行。”她的一句话将我的思绪从遥远的地方拉了回来。
我看了她一眼,她继续说道:“咱们要攒够 200 万,你看现在还差多少?”
这个攒够 200 万的话,其实说过很多次了。之前我总是说,没关系,我会尽量去攒够的,永远不退休,等哪天我死也要死在工作岗位上。
只是,今天我不想回应了。内心的想法有时候不想告诉任何人,自己的兄弟姐妹,伴侣,父母,都不想诉说,甚至连表现都不想表现出来。
我越过她,去上了趟厕所,回来之后关了灯。钻进被窝里,背对着她,朝着墙蜷缩起来。
过了会儿,她贴在了我的后面,轻轻的说了一句:“怎么了?自闭了?”
“没有,我只是困了”,我答道,一滴眼泪也在这时坠落在了枕头上。