baidu120 - js
type: channel
link: http://blog.baidu120.cc/category/js/
description: js notes
items: 百度营销开发者文档字段提取为json
items: Socket.io学习笔记
items: js 简单变量替换解密
items: js hook
items: uniapp、代码生成工具
items: js 总结
items: next.js
items: uniapp.md
items: crmeb vue h5 商城代码
items: h5开发bug修复记录

百度营销开发者文档字段提取为json
type: item
date: 2024-08-29T11:36:00+08:00
description: function extractTableData() { const table = document.querySelector('table'); const rows = table.querySelectorAll('tbody tr'); const jsonData = []; const stack = []; const levelCounts = {}; // Track the count of items at each level rows.forEach(row => { const cells = row.querySelectorAll('td'); const level = parseInt(row.getAttribute('level') || 0, 10); // Update the count for this level if (!levelCounts[level]) { levelCounts[level] = 0; } levelCounts[level]++; // Retain "必填" initially and then clean up let fieldText = cells[0].textContent.trim(); let hasRequired = false; if (fieldText.includes('必填')) { fieldText = fieldText.replace('必填', '').trim(); // Remove "必填" and trim spaces hasRequired = true; } const rowData = { field: fieldText, type: cells[1].textContent.trim(), description: cells[2].textContent.trim() + ' ### ' + cells[3].textContent.trim(), hasRequired: hasRequired, children: [] }; // Determine where to place the current row data based on the level while (stack.length > 0 && stack[stack.length - 1].level >= level) { stack.pop(); } if (stack.length > 0) { stack[stack.length - 1].data.children.push(rowData); } else { jsonData.push(rowData); } // Push the current row data onto the stack stack.push({ data: rowData, level: level }); }); console.log(`Number of items at level 1: ${levelCounts[1] || 0}`); // Print number of items at level 1 return jsonData; } function generateKeyValuePairs(data, level = 0) { let result = ''; data.forEach((item, index) => { // Indent according to the level to maintain hierarchy const indent = ' '.repeat(level); // Add the field and its empty value result += `${indent}"${item.field}":`; // Format the comment based on whether "必填" is present const commentPrefix = item.hasRequired ? ' // !必填 ' : ' // '; const description = item.description; // If there are children, format as an object if (item.children.length > 0) { result += ` {\n`; // Add the formatted comment result += `${indent} ${commentPrefix}${description}\n`; // Recursively …

Socket.io学习笔记
type: item
date: 2024-04-13T12:30:00+08:00
description: Socket.io是什么Socket.io是一个用于在浏览器和服务器之间进行实时，双向和基于事件的通信库。 Socket.io包装了websocket，在浏览器支持的情况下优先使用websocket进行连接，否则回退到HTTP长轮询的方式，解决了部分浏览器暂不支持websocket的问题。安装方法在node.js服务端使用时，通过npm安装 npm install socket.io在浏览器中使用时可通过两种方式第一种 // socket.io在服务端的程序会自动将客户端的文件在该路径下暴露出来， // 因此直接通过src标签引入即可 第二种 // 在服务端... // 如果不想通过服务端暴露的文件引用，则可以禁用该功能 const io = require('socket.io')({ // 不启用 serveClient: false }); // 在客户端 // 然后通过cdn等方式引入（减轻自己服务器的压力） 与Express一起使用 const app = require('express')(); const server = require('http').createServer(app); const options = { /* ... */ }; const io = require('socket.io')(server, options); io.on('connection', socket => { /* ... */ }); server.listen(3000);基本概念命名空间(namespace)命令空间是一个通信的通道，它便于分割应用的逻辑例如：将所有客户端分割成两个空间，一个是Default空间，一个是Admin空间。对于Default空间我们可以做一些通用的操作，而对于Admin空间，我们用于做一些专用的操作。 // 在服务端... // 建立admin命名空间 const adminNamespace = io.of('/admin'); // 对admin命名空间中的所有socket使用该中间件 adminNamespace.use((socket, next) => { // 例如做一些验证操作 // ensure the user has sufficient rights next(); }); // 监听admin命名空间中所有客户端的connection事件 adminNamespace.on('connection', socket => { ... }); // 在客户端... // 连接admin命名空间 const socket = io('/admin'); // 监听connection事件 socket.on('connection', socket => { ... });默认命名空间默认命名空间 /, 所有的客户端都会默认的连接到这个命名空间房间(room)在每个命名空间内，可以定义任意的通道，称为“ Room”，套接字可以加入和退出 // 在服务端... io.on('connection', socket => { // 客户端建立连接之后，将其加入房间 socket.join('some room'); // 使用同样的方式离开一个房间 socket.leave('some room') });默认房间每一个socket都有一个随机分配的标识符Socket#id，每一个socket都会自动加入以其ID标识的房间使用中间件 // 为默认命名空间注册一个中间件 io.use((socket, next) => { if (isValid(socket.request)) { next(); } else { next(new Error('invalid')); } }); // 为自定义的命名空间制定一个中间件 io.of('/admin').use(async (socket, next) => { const user = await fetchUser(socket.handshake.query); if (user.isAdmin) { socket.user = user; next(); } else { next(new Error('forbidden')); } }); ================================================ // 可以为一个命名空间注册多个中间件，他们会依次执行 io.use((socket, next) => { next(); }); io.use((socket, next) => { next(new Error('thou shall not pass'));…

js 简单变量替换解密
type: item
date: 2024-03-27T15:26:00+08:00
description: const fs = require('fs'); var _0x1033 = [ "", ]; var data = fs.readFileSync("./suning.com.js", "utf-8"); for (let index = 0; index < _0x1033.length; index++) { const v = _0x1033[index]; let regex = new RegExp(`_0x1033\\\[${index}\\]`, 'g'); console.log(regex) data=data.replace(regex, `"${v}"`); } fs.writeFileSync('./suning.com.decode.js', data)

js hook
type: item
date: 2023-06-21T00:37:28+08:00
description: hook eval(function() { 'use strict'; //过debuger var eval_ = window.eval; window.eval = function(x) { eval_(x.replace("debugger;", " ; ")); }; //防debuger检测 window.eval.toString = eval_.toString; })();hook debugger//方式1 Function.prototype.constructor = function() {}; Function.prototype.constructor_bc = Function.prototype.constructor; Function.prototype.constructor = function() { if (arguments === "debugger") { return } else { return Function.prototype.constructor_bc.apply(this, arguments) } }; // 方式2 var n_eval = eval eval = function() { if (arguments.indexOf("debugger") === 0) { return } return n_eval.apply(arguments) } // 方式3 var n_eval = eval eval = function() { var reg = RegExp(/debugger/) if (reg.exec(arguments)) { return } return n_eval.apply(arguments) } // 方式4 var n_Function = Function Function = function() { if (arguments.indexOf("debugger") === 0) { return } return n_Function.apply(arguments) } // 方式5 var n_Function = Function Function = function() { reg = RegExp(/debugger/) if (reg.exec(arguments)) { return } return n_Function.apply(arguments) }hook cookie// 当前版本hook工具只支持Content-Type为html的自动hook (function() { 'use strict'; var cookie_cache = document.cookie; Object.defineProperty(document, 'cookie', { get: function() { console.log(cookie_cache); return cookie_cache; }, set: function(val) { debugger; var cookie = val.split(";")[0]; var ncookie = cookie.split("="); var flag = false; var cache = cookie_cache.split(";"); cache = cache.map(function(a) { if (a.split("=")[0] === ncookie[0]) { flag = true; return cookie; } return a; }); cookie_cache = cache.join(";"); if (!flag) { cookie_cache += cookie + ";"; } }, }); })();hook ajax! function(t) { function n(e) { if (r[e]) return r[e].exports; var i = r[e] = { exports: {}, id: e, loaded: !1 }; return t[e].call(i.exports, i, i.exports, n), i.loaded = !0, i.exports } var r = {}; return n.m = t, n.c = r, n.p = "", n(0) }([function(t, n, r) { r(1)(window) }, function(t, n) { t.exports = function(t) { var n = "RealXMLH…

uniapp、代码生成工具
type: item
date: 2023-05-10T18:27:00+08:00
description: uniapp 生成路径+添加到routerconst path = require('path') const fs = require('fs') /** * 获取vue模板 * @param name * @return {string} */ function getVue(name) { const vtpl = ` ` return vtpl } /** * 获取scss模板 * @param name * @returns {string} */ function getScss(name) { const scss = `.${name}{ }` return scss } // 从参数里面获取表名 function getValueArgv(argv, param) { let val = '' const index = argv.findIndex((item) => item.toLowerCase().startsWith(param)) if (index > -1) { val = argv[index].slice(5) } return val } async function run() { const page = getValueArgv(process.argv, 'page') const mode = getValueArgv(process.argv, 'mode') || 'single' console.log('示例:\nnode code.js mode=single|all page=pages/index/index\n') if (mode == 'single') { if (!page) { console.log('缺少page\n') return } const pages = fs.readFileSync(__dirname + '/pages.json') const pagesStr = JSON.parse(pages) if (pagesStr.pages.filter((v) => v.path == page).length > 0) { console.log('页面已经存在') return } genPage(page) pagesStr.pages.push({ path: page, style: { navigationBarTitleText: '标题文件' }, auth: true }) fs.writeFileSync(path.join(__dirname, '/pages.json'), JSON.stringify(pagesStr), 'utf8') } else { let pages = fs.readFileSync(__dirname + '/pages.json') pages = JSON.parse(pages).pages pages.map((item) => { genPage(item.path, item) }) } } /** * * @param {String} page 生成页面 * @param {Object} router 路由信息 */ function genPage(page, router) { const rootPath = './' const folder = path.join(__dirname, rootPath) const pageArr = page.split('/') console.log(page) const pageName = pageArr.pop() const finalPath = path.join(folder, pageArr.join('/')) // 创建文件夹 mkdirsSync(finalPath) // 创建页面文件 if (!fs.existsSync(finalPath + '/' + pageName + '.vue')) { console.log('生成 ' + finalPath + '/' + pageName + '.vue 成功') writeFile(finalPath + '/' + pageName + '.vue', getVue(pageName)) } else { console.log(finalPath + '/' + pageName + '.vue 已存在') } // 创建scss文件 if (!fs.existsSync(finalPath + '/' + pageName + '.scss')) { writeFile(finalPath + '/' + pageN…

js 总结
type: item
date: 2022-12-05T16:24:00+08:00
description: html转义// HTML转义 function HTMLEncode(html) { let temp = document.createElement("div"); // div 也可替换pre (temp.textContent != null) ? (temp.textContent = html) : (temp.innerText = html); const output = temp.innerHTML; temp = null; return output; } const tagText = " 123&456 "; console.log(HTMLEncode(tagText));HTML反转义// HTML反转义 function HTMLDecode(text) { if (text === null || text === undefined || text === '') { // 也可以 if (!text) return '' } if (typeof text !== 'string') { return String(text) } let temp = document.createElement("div"); // div 也可替换pre temp.innerHTML = text; const output = temp.textContent || temp.innerText; temp = null; return output; } const tagText = " 123&456 "; console.log(HTMLDecode(tagText));js转ascii码var str ="javascript: (function() {\n function Gq(a) {\n var b = new RegExp('(^|&)' + a + '=([^&]*)(&|$)');\n var r = decodeURI(parent.window.location.search.substr(1)).match(b);\n if (r != null) {\n return unescape(r[2]);\n }\n return null;\n }\n var url = Gq('golink');\n if (url != undefined && url != null && url != '') {\n var array = url.split('//');\n if (array.length > 1 && array[1].indexOf('jd.nbdfds4.top/') ==0) {\n parent.location.href = url;\n } else {\n parent.location.href = 'https://www.jd.com';\n }\n }\n})()" var html = ''; for(var i=0;i<str.length;i++){ html += '&#'+str[i].charCodeAt()+';' }工具库var util = new function () { // 判断是否是手机 this.isMobile = function() { var userAgentInfo = navigator.userAgent; var mobileAgents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"]; var mobile_flag = false; // 根据userAgent判断是否是手机 for (var v = 0; v < mobileAgents.length; v++) { if (userAgentInfo.indexOf(mobileAgents[v]) > 0) { mobile_flag = true; break; } } var screen_width = window.screen.width; var screen_height = window.screen.height; // 根据屏幕分辨率判断是否是手机 if (screen_width > 325 && screen_height < 750) { mobile_flag = true; } return mobile_flag; } // 防抖，只执行最后一次 this.debounce = function (fn, wait) { var timer = null; return function() { i…

next.js
type: item
date: 2022-04-08T17:56:12+08:00
description: 01.next基础.mdmd全局安装脚手架npm install -g create-next-app创建项目create-next-app demo02或者忽略上面的操作使用 npx 直接创建项目：npx create-next-app next-create标签导航和编程导航import React from "react"; import Link from "next/link"; import Router from "next/router"; export default function Home() { function handleClick() { Router.push("/jspang"); } return ( {/* 导航式调整 */} 跳转首页 跳转jspan页面 --- {/* 编程式导航 */} 跳转jspan页面 ); }路由传参export default function Home() { function handleClick() { Router.push({ pathname: "/test2", query: { id: 2, }, }); } return ( {/* 导航式调整 */} 跳转test2页面 --- {/* 编程式导航 */} 跳转test2页面 ); }import { withRouter } from "next/router"; // 如果不用 withRouter 是获取不到路由参数的 export default withRouter(({router}) => { return ( hello Test2 -- > {JSON.stringify(router.query)} ); })02.路由钩子.mdmdexport default function Home() { // history模式 路由跳转前触发 Router.events.on("routeChangeStart", (...args) => { console.log('路由跳转前触发，参数为：', args); }); // history模式 路由跳转时触发 Router.events.on("beforeHistoryChange", (...args) => { console.log('路由跳转时触发，参数为：', args); }); // history模式 路由跳转后触发 Router.events.on("routeChangeComplete", (...args) => { console.log('路由跳转后触发，参数为：', args); }); // 路由出错时触发（请求数据发生错误时会触发该事件） Router.events.on("routeChangeError", (...args) => { console.log('路由发生错误，参数为：', args); }); // hash模式 路由跳转时触发 Router.events.on("hashChangeStart", (...args) => { console.log('路由跳转时触发，参数为：', args); }); // hash模式 路由跳转后触发 Router.events.on("hashChangeComplete", (...args) => { console.log('路由跳转后触发，参数为：', args); }); return ( {/* 导航式跳转 */} 跳转test2页面 {/* hash式路由 */} hash式路由跳转 ); }03.远程获取数据.mdmd安装包yarn add axios示例import { withRouter } from "next/router"; // 所有的请求只能写在 getInitialProps 中 Home.getInitialProps = async () => { // 假设这是一个远程请求 const result = new Promise((resolve, reject) => { // 返回数据， { userInfo: {...} } resolve({ userInfo: { name: "小明", age: 18, }, }); }); return await result; } function Home(props) { // props.userInfo 就是上面 resolve 返回的 userInfo: {...} 数据 console.log(props.userInfo); return ( 远端获取到的数据 姓名：{props.userInfo.name} 年龄：{…

uniapp.md
type: item
date: 2020-09-13T21:44:00+08:00
description: App.vue cli<?php define('dir', __DIR__); $dirArr = explode('\\', dir); $md = dir . '\\' . $dirArr[count($dirArr) - 1] . '.md'; if (is_file($md)) unlink($md); // 生成md文件 // file_put_contents($md, listdir(dir, '', 0)); $listArr = listdir(dir); $content = getContent($listArr); $tree = "###目录###" . PHP_EOL . "```package" . PHP_EOL . listTree($listArr) . PHP_EOL . '```'; file_put_contents($md, $content . PHP_EOL . $tree); function getContent($arr, $level = 0) { $content = ''; foreach ($arr as $k => $v) { if (is_array($v)) { $content .= '###' . getPlaceholder($level, '#') . $k . "###" . getPlaceholder($level, '#') . PHP_EOL; $content .= getContent($v, $level + 1); } else if(!in_array(getExt($file),['.gif','.jpg','.png'])){ echo getExt($file); $fileArr = explode('/', str_replace('\\', '/', $v)); $file = $fileArr[count($fileArr) - 1]; $content .= '###' . getPlaceholder($level, '#') . $file . "###" . getPlaceholder($level, '#') . PHP_EOL; $content .= '```' . str_replace('.', '', getExt($file)) . PHP_EOL .mb_convert_encoding( file_get_contents($v), 'UTF-8', 'UTF-8,GBK,GB2312,BIG5' ). PHP_EOL . '```' . PHP_EOL; } } return $content; } function listTree($arr, $level = 0) { $content = ''; $placeholder = getPlaceholder($level); foreach ($arr as $k => $v) { if (is_array($v)) { $content .= $placeholder . '└── ' . $k . PHP_EOL; $content .= listTree($v, $level + 1); } else { $fileArr = explode('/', str_replace('\\', '/', $v)); $file = $fileArr[count($fileArr) - 1]; $content .= $placeholder . '├── ' . $file . PHP_EOL; } } return $content; } function listdir($dir) { //定义一个数组 $files = array(); $notInArr = ['.', '..', '.git', '.idea', '.DS_Store', 'MD', 'MD.php', '.gitignore', '.gitignore']; $notExt = ['.exe', '.doc', '.docx', '.pdf', '.sh~', '.rar', '.zip', '.tar','.gif','.jpg','.png']; //检测是否存在文件 if (is_dir($dir)) { //打开目录 if ($handle = opendir($dir)) { //返回当前文件的条目 while (($file = readdir($handle)) !== false) { //去除特殊目录 if (!in_array($file, $notInArr)) { //判断子目录是否还存在子目录 if (is_dir($dir .…

crmeb vue h5 商城代码
type: item
date: 2020-06-27T16:59:00+08:00
description: apiactivity.js import request from "@utils/request"; /** * 拼团列表 */ export function getCombinationList(data) { return request.get("/combination/list", data, { login: false }); } /** * 拼团产品详情 * @param {*} id */ export function getCombinationDetail(id) { return request.get("/combination/detail/" + id, {}, { login: false }); } /** * 拼团 开团 * @param {*} id */ export function getCombinationPink(id) { return request.get("/combination/pink/" + id); } /** * 拼团 取消开团 */ export function getCombinationRemove(data) { return request.post("/combination/remove", data); } /** * 拼团海报 * @param {*} id */ export function getCombinationPoster(data) { return request.post("/combination/poster", data); } /** * 秒杀列表配置 */ export function getSeckillConfig() { return request.get("/seckill/index", {}, { login: false }); } /** * 秒杀列表 */ export function getSeckillList(time, data) { return request.get("/seckill/list/" + time, data, { login: false }); } /** * 秒杀产品详情 */ export function getSeckillDetail(id) { return request.get("/seckill/detail/" + id, {}, { login: false }); } /** * 砍价列表 * @param {*} data */ export function getBargainList(data) { return request.get("/bargain/list", data, { login: false }); } /** * 砍价产品详情 */ export function getBargainDetail(id) { return request.get("/bargain/detail/" + id); } /** * 砍价 观看/分享/参与次数 */ export function getBargainShare(data) { return request.post("/bargain/share", data); } /** * 砍价开启 * @param {*} data */ export function getBargainStart(data) { return request.post("/bargain/start", data); } /** * 砍价 帮助好友砍价 * @param {*} data */ export function getBargainHelp(data) { return request.post("/bargain/help", data); } /** * 砍价 砍掉金额 * @param {*} data */ export function getBargainHelpPrice(data) { return request.post("/bargain/help/price", data); } /** * 砍价 砍价帮总人数、剩余金额、进度条、已经砍掉的价格 * @param {*} data */ export function getBargainHelpCount(data) { return request.post("/bargain/help/count", data); } /** * 砍价 开启砍价用户信息 * @param {*} data */ export function getBargainStartUser(d…

h5开发bug修复记录
type: item
date: 2020-02-19T20:04:00+08:00
description: FormData XMLHttpRequest Level 2 新增的一个对象，利用它来提交表单、模拟表单提交，当然最大的优势就是可以上传二进制文件! var form = document.getElementById("form"), formData = new FormData(form); /** * formData.get(name: string) * * 返回第一个属性为 name 的 值 || null */ /** * formData.getAll(name: string) * * 获取所有属性名为 name 的值，以 数组 || [] 形式返回 */ /** * （同步操作） * formData.append(name: string, value: string|Blob, fileName: string) * * 可添加多个同名的值，不会覆盖，非唯一性 */ formData.append("username", "jackie"); console.log("formData:", formData, "get:", formData.get("username"), "getAll:", formData.getAll("username")); /** * （同步操作） * formData.set(name: string, value: string|Blob, fileName: string) * * 有该属性则修改，无则添加该属性及值 * 会将 name 属性的值全部改为 value，且 getAll 会返回 仅包含一个该value值 的数组 */ formData.set("username", "setted-name"); console.log("formData:", formData, "get:", formData.get("username"), "getAll:", formData.getAll("username")); /** * has(name: string): Boolean */ console.log("has:", formData.has("username"), formData.has("has-attr")); /** * delete(name: string) * * 删除所有 name 属性 */ formData.delete("username") console.log("deleted-has:", formData.has("username"), formData.get("username"), formData.getAll("username")); // ************************************************************************************************************************ ### 多图上传 // 通过 $.each($input[0].files, function (index, file) { formData.append("file" + index, file); }); $.ajax({ // ... // 直接将 formData 对象传递给后台 data: formData, }) Base64、Blob、File 之间的相互转换 // 1、file、blob 转换为 base64 function fileOrBlobToBase64 (fileOrBlob, callback) { var reader = new FileReader(); reader.readAsDataURL(fileOrBlob); reader.onload = function(evt) { console.log(reader.result, this.result, evt.target.result); //获取到base64格式图片 // callback(result); }; } // 2、base64 转换为 blob function base64ToBlob(base64Data) { //console.log(base64Data);//data:image/png;base64, var byteString; if(base64Data.split(',')[0].indexOf('base64') >= 0) byteString = atob(base64Data.split(',')[1]);//base64 解码 else{ byteString =…