首页
友链
壁纸
留言
今日热榜
更多
关于
时光
推荐
精品流量卡
Search
1
都二十多年了,你的梦为什么还没碎!
57,091 阅读
2
2022年5个好用的 BT/ 磁力链接下载工具推荐 |Windows 、安卓系统
37,384 阅读
3
nps内网穿透实现外网访问树莓派
32,427 阅读
4
实践利用宝塔建emlog个人博客-超详细【原创】
26,134 阅读
5
Typecho-Joe-Theme主题帮助文档
24,632 阅读
闲杂乱码
Python
网站源码
微信小程序
娱乐分享
Is相册
软件工具
登录
Search
标签搜索
PHP
HTML
API
Javascript
源码
JS
Vue
Github
CloudFlare
接口
函数
SQL
ASP.NET
MVC
EF
T4模板
后台管理
CDN
微信小程序
MAC
韩小韩
累计撰写
262
篇文章
累计收到
1,305
条评论
首页
栏目
闲杂乱码
Python
网站源码
微信小程序
娱乐分享
Is相册
软件工具
页面
友链
壁纸
留言
今日热榜
关于
时光
推荐
精品流量卡
搜索到
261
篇与
韩小韩
的结果
2022-12-02
利用CloudFlare的Workers和Pages反代Github并缓存实现Github文件加速访问
{message type="info" content="众所周知Github是全球最大的代码托管平台,我们可以通过使用GitHub学习知识、发现优秀的开源软件,也可以上传自己的项目或文件。但对于国内的同学来说,如果不挂代理,访问Github是不太稳定的,且下载巨慢。网上有很多Github加速访问的方法,如果你也想拥有一个属于自己独享的Github加速,可以按照此教程搭建一个你自己的反代来实现加速Github文件访问的服务。"/}CloudFlare{callout color="#f0ad4e"}CloudFlare提供的不仅仅是CDN,而是一个快速、敏捷、安全的全球网络。CloudFlare通过全球边缘网络实现超快速的静态和动态内容交付。对内容的高速缓存方式实行精确控制,降低带宽成本,并充分利用内置的不计量 DDoS 保护。今天我们使用 CloudFlare Workers 和 CloudFlare Pages来搭建我们的反代服务。{/callout}通过CloudFlare Workers实现反代{callout color="#f0ad4e"}没有CloudFlare账号可以去简单注册一个,以后肯定必然会用的到!首先,创建一个CloudFlare Workers服务,步奏如下图。{/callout}{gird column="2" gap="15"}{gird-item}{/gird-item}{gird-item}{/gird-item}{/gird}{callout color="#f0ad4e"}创建好以后,编辑CloudFlare Workers服务,并写入以下代码即可。{/callout}addEventListener( "fetch",event => { let url=new URL(event.request.url); url.hostname="cdn.jsdelivr.net"; //你需要反代的域名 let request=new Request(url,event.request); event. respondWith( fetch(request) ) } ){gird column="2" gap="15"}{gird-item}{/gird-item}{gird-item}{/gird-item}{/gird}{callout color="#f0ad4e"}由于CloudFlare Workers自带的免费works.dev域名国内已经无法访问了,需要通过绑定自定义域名.{/callout}{gird column="3" gap="15"}{gird-item}{/gird-item}{gird-item}{/gird-item}{gird-item}{/gird-item}{/gird}{callout color="#f0ad4e"}绑定好域名,我们就可以直接访问了!{/callout}通过CloudFlare Pages实现反代{message type="info" content="因为CloudFlare Pages可以连接Github,所以我们有两种方案1.直接上传反代脚本.2.将脚本文件托管在Github上,可实时更新."/}1.直接上传反代脚本.{callout color="#f0ad4e"}首先创建CloudFlare Pages服务,选择直接上传.{/callout}{gird column="2" gap="15"}{gird-item}{/gird-item}{gird-item}{/gird-item}{/gird}{callout color="#f0ad4e"}然后创建一个项目文件夹(名字可以随意),在文件夹内创建一个_worker.js的文件,并写入以下代码:{/callout}export default { async fetch(request, env) { const _url = new URL(request.url); _url.hostname = _url.pathname.startsWith("/gh/") ? "cdn.jsdelivr.net" : "www.baidu.com"; const req = new Request(_url, request); return fetch(req); }, };{callout color="#f0ad4e"}将项目文件夹拖拽到上传区域进行上传(注意:是上传项目文件夹),然后部署项目.{/callout}{gird column="2" gap="15"}{gird-item}{/gird-item}{gird-item}{/gird-item}{/gird}2.将脚本文件托管在Github上,可实时更新.{callout color="#f0ad4e"}首先创建一个Git项目,然后creating a new file 一个_worker.js的JS文件并写入以下代码保存.{/callout}export default { async fetch(request, env) { const _url = new URL(request.url); _url.hostname = _url.pathname.startsWith("/gh/") ? "cdn.jsdelivr.net" : "www.baidu.com"; const req = new Request(_url, request); return fetch(req); }, };{gird column="4" gap="15"}{gird-item}{/gird-item}{gird-item}{/gird-item}{gird-item}{/gird-item}{gird-item}{/gird-item}{/gird}{callout color="#f0ad4e"}然后创建CloudFlare Pages服务,选择连接到Git,选择你刚刚创建的Git项目,开始设置。使用默认配置,并保存部署即可。{/callout}{gird column="3" gap="15"}{gird-item}{/gird-item}{gird-item}{/gird-item}{gird-item}{/gird-item}{/gird}{callout color="#4def86"}到此,我们通过CloudFlare Pages创建的服务已经成功了.{/callout}{callout color="#f0ad4e"}由于CloudFlare Pages自带的免费pages.dev域名国内访问也是很不稳定,这里极其建议同学们绑定自定义域名进行访问!方法也很简单,首先打开CloudFlare Pages,选择你刚刚创建的服务然后 点击自定义域 => 设置自定义域名 => 进行CNAME解析 => 激活域 即可大功告成!{/callout}{gird column="3" gap="15"}{gird-item}{/gird-item}{gird-item}{/gird-item}{gird-item}{/gird-item}{/gird}以上内容,我们已经完成了两种反向代理的搭建,大家自行选择一种,坚持能跑就行的原则,继续接下来的缓存步骤.配置Github加速文件的边缘缓存{callout color="#f0ad4e"}选择你得域名,点击 规则 => 页面规则 => 创建页面规则如图所示,设置以下规则,并保存部署页面规则即可.{/callout}{gird column="3" gap="15"}{gird-item}{/gird-item}{gird-item}{/gird-item}{gird-item}{/gird-item}{/gird}{callout color="#f0ad4e"}最后我们访问一下,感受一下速度~{/callout}今天也是一只白嫖怪噢~
2022年12月02日
1,666 阅读
0 评论
1 点赞
2022-11-25
简单逆向某色情网站图片加密(原创)
{message type="info" content="今天,一Py哥们为民除害爬取某色情网站的时候,遇到了一点点小问题,关于色色电影列表中视频封面数据的问题,我简单的看了一下,我也是第一次见到这种,挺有意思的封面图片渲染,所以单拉出来我们一起来看看!"/}图片地址SRC{callout color="#f0ad4e"}审查元素查看图片地址是 Base64 地址,并不是网络地址,不会被墙,根据用户网速加载,不占用服务器带宽,挺好的。控制台的数据是没有任何问题的,然后又看了一下源代码。{/callout}IMG标签中的Origanal数据{callout color="#f0ad4e"}我从源代码中查看 IMG 标签并没有发现 SRC 属性,但是看到了一个有意思的属性,data-origanal,直觉告诉我,这个数据并不简单,然后我分页加载了一下视频看到加载图片时会加载data-origanal对应的TXT文件。{/callout}{callout color="#f0ad4e"}当我打开TXT文件看了一下其中的数据,第一眼的感觉就是Base64加密数据,呀,太简单了,肯定是图片的Base64地址,我立马和封面的Base64图片地址对比一看,一点都不一样!我又想了一下,难道是图片地址再Base64了一下?然后我继续Base64解密了一下。{/callout}{callout color="#f0ad4e"}乱七八糟,这不是Base64数据,那肯定就是AES加密咯,一个色情网站怎么还花里胡哨!{/callout}JS文件简单剖析{callout color="#f0ad4e"}全局搜索了一下 data-origanal 和 origanal关键词,,发现了其中一个文件并找打了有关的函数,利用Ajax请求获取TXT文静中的数据,然后并传入一个函数进行解密。{/callout}{callout color="#f0ad4e"}继续搜索关键词 desDecrypt 找到了一个eval加密JS文件。{/callout}{callout color="#f0ad4e"}简单解密了一下,取到了原始函数,截取我们主要用到的两个函数,一个加密,一个解密,如下。{/callout}// 秘钥 let asc_key = "jeH3O1VX"; let base_lv = "nHnsU4cX"; // 加密 function desEncrypt(a) { let tmpiv = CryptoJS.enc.Utf8.parse(base_lv); let key = CryptoJS.enc.Utf8.parse(asc_key); var b = CryptoJS.AES.encrypt(a, key, { iv: tmpiv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7, formatter: CryptoJS.format.OpenSSL, }); return b.ciphertext.toString(CryptoJS.enc.Base64); } // 解密 function desDecrypt(a) { a = a.replace(/\s*/g, ""); let tmpiv = CryptoJS.enc.Utf8.parse(base_lv); var b = CryptoJS.enc.Utf8.parse(asc_key); var c = CryptoJS.DES.decrypt( { ciphertext: CryptoJS.enc.Base64.parse(a) }, b, { iv: tmpiv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7, formatter: CryptoJS.format.OpenSSL, } ); return c.toString(CryptoJS.enc.Utf8); }{callout color="#f0ad4e"}执行函数并调用了一下解密函数,手动传入了TXT文件中AES加密的数据,并取到了封面图片IMG标签的SRC地址。{/callout}个人看法{callout color="#f0ad4e"}从文件数据的加密解密还是JS中关键函数的eval加密来说,整体流程走下来,没有任何难度,连麻烦都算不上,怎么说呢,他是用心了还是没用心,我也说不上来。但这个图片渲染的方式我还是第一次见。如果这个加密如果是为了防爬,我个人认为简直太弱了。从图片地址加密前后对比来说,加密后的图片地址,也就是TXT文件中的数据比原始图片地址数据大了好多,是挺鸡肋的。{/callout}总结{callout color="#f0ad4e"}今天发现了一个挺有意思的小东西~{/callout}
2022年11月25日
1,383 阅读
21 评论
6 点赞
2022-11-19
骚扰电话API接口 开源
{message type="info" content="根据 服务器接口数量、带宽、可维护性等多种因素,韩小韩API接口站决定下架骚扰电话API接口,不过由于使用量过大,突然下架是对用户的不负责,故将骚扰电话接口开源,供大家直接使用或二次修改使用。"/}骚扰电话查询API{abtn icon="fa-link" color="#9f1ff4" href="https://api.vvhan.com/saorao.html" radius="" content="骚扰电话查询API - 韩小韩API接口"/} 骚扰电话查询API源码<?php /* * @Author: Han * @Date: 2021-10-26 10:12:07 * @LastEditors: Han * @LastEditTime: 2022-02-16 13:24:53 * @FilePath: \saoraotel.php */ // error_reporting(0); header("Access-Control-Allow-Origin:*"); header('Content-type:application/json; charset=utf-8'); // API调用统计 // include './sum/db/apicount.php'; // hansCount("saorao"); $tel = isset($_GET['tel']) && $_GET['tel'] != '' ? $_GET['tel'] : exit(json_encode(['success' => false, 'message' => '参数不完整'], JSON_UNESCAPED_UNICODE)); strlen($tel) != 11 && exit(json_encode(['success' => false, 'message' => '手机号码不正确'], JSON_UNESCAPED_UNICODE)); // 百度的 $_KEYRES = getKD('https://miao.baidu.com/abdr', 'eyJkYXRhIjoiMzZmNGY3MGY3MzA5YTA0MDFlNTQyNDRjYmVlZmNmMjU5ZWJjYjZkMzUxYmY4NDVlZTgwMDI4OGVlOWYzZWFkODAyNGFhZmUzOGNkNDBjNmExZGIyZmQzOGI5OWFiM2E3ODhmYmJlY2I5ZTliMWU4YmRkNmM1MmQ1OTI1ZDNkMDcyNjE0NGNiMDQxNzRkMzE1OTBmYWFmZDEwN2U4NmEzNjk1N2I1ODExMjEzMzllYmFlYWE3NjY2YzcwMjAwOTNhMGQ3Mjk5OWM4MmRkNGY1ZDU0OWE0MWIxMjdiYmJhOTg1ODQ5MDcwODNhZTAxZjhmMzY2OTI1MzQwZDA4NzlmZWRjZGE1YTdhZWMzNDFlYmNkMTBhOTU0MGVkMDM0NjIzZDg3MDg5OTY0NzU2NDQyY2E3YmIwYzIwMGI5OGIzY2NmZjNhNjAzMzY1MGYzMWUxYWRjZDUyZTI0YzlhZjRmMGQyM2E5ODY3MDQ2YjhhNjVlYzNkNjNiMDlmYjUyZTkzZTI5OGFiZDlhOTY4NDE3ZmYxODEwY2I1NWViODQyOGFlNTUyNDU2NjYzODQ5NjMwYjBkYWY1ODljMWRiMWFhMDM3MGUyYWJjZmE3MzU0ODY4OWE1Mjc5ODhlOTMxZjk3Mzc1MjJlYjg5NWM1YjVjMDJjYTNmYWFlNzJjMDIzZDdkY2NhOTExZmMyMmFmOGJhMmQ4MzgzYWZkY2Q2OTVkOWZmNDE4ZGUyODA4NzIxOTBhOTY2MGMyNjBhYmQ1ZDFjOWIxOWQ2OTNlNjFjMmMzOGQ2ZDNmYWU0N2JiMmRiNzUwNDhjYjk0NWIyY2YyNjA3NWVmNDk1MTYwOGY5OTkxYjcwYjEyMTYzZDM1MDc3ZTM0NmEwODZmYTYzNmQ0NGEwMDEzODk1NWU2OGE1NGM1YTUxY2Y4ZGI3MDkyNjJjNjZlNWFhYmFiNGZiOGQ4MWU0ODI1NjAxNWY1OTc3ZTNlODAzMzY5OTJhYWJjZDc2NjU2MzZkOGJiMTFiZjQzYzkyNTM1MWMxY2VmNjk3N2FjNDNhNjc2NDE3MzQ4ZjQ0MzEwYWNiMDVmMzQ3Yzk2MmRkY2FiZDRhNTIyOTRjYzZmODA4NDJhMDU4MjAzNzY4MTE3NTUxZmIzN2M2ZmNiMjFhNmIxODI0MzViNzIzMTEzYzYwMjFjNDA1YjcwYzBhZTg2Njc5YzRiZTIwNTEwNGY3OGFhNjg5ZDFhOTAwMTQwMmY0NWY5ZjU2NmUxMDRhOTI1YzI5YTFkMGE4MjZlNWUwZjkxYTAzMDRlYjZmNzkwMjE3Y2Q2N2NmYjVjMGQyN2FmNTg3Y2Y4MzU4ZmQxYzU1NDc2NmM4OTczYzUxY2Y5NDhiNTI1Yjk5ODBhZjFmZTM2ODRiN2FkOTkwZWNlMmVkMTljZTJjMDU5ZmZmMzU1YTFiZDcwOTRjMzFiM2Y3MzJmMTY5YTY2N2Y3ZDI5NDljYmFiMWY5OGFlMTViMGI2MjQzYmI3N2ViNDEwY2FlYmNlYzY3OTAyZGY2ZDdlMGEwYTc3NmM2MTRkMDc2ODgwMzRmMTI0YTVkMDE5MWVlMzZiMjVhZGU2MzQxNmE0NzI0YzhmY2E2ZTExNjQ0MGE2NTk1ZGZjZmZmMTc4Zjg1YWI1NzgxYjVlYjEyNzA2ZWM0MmRiYjU5ZmE2M2Y2NDc2NzdiMjI2NjU0YzA5OTM1YzM3ODdiYzEyY2RlNjU2Mzg5MjI2ZjYyZDMwODQ3ZTk4ZDUwMzUxY2VkNTE5NWNiMTM4ZmQzZWYwZjMwNmVhODE3MGJiOWE2MjIwZTJjYzliNTk1NWQ0NmFkYzliZjNiODBkN2E3N2E1ZjBiN2NkNDZhYTEyZjk5MTNiNTE5ZjQ5NzNiZDU3NWU0NjAzY2E0NzBjNmYyODhkNGQwMmMwZWRjYTA1OTE2ZjNjYzExNmRiMjdhYzJmZjUyNDhmZjQwYTUyY2YyOWVlMDA0NGQ2YWQwNGI0Yzk0NDI5MWQ0MjNkZWNhYTliYmQ2ZGYxOTYxNTRlMzE3OTAxOTNhY2JkZjcxYjk3ZDU3Y2JkMjI4OGIyNjkzZjBkMjE0MGVkMjg3NzE3NGMyYzNiYWE0ZmZiYTU3OTczMGQ1MzU1MWI1NDA4NDZkYjkzNWU2Zjg5ZGIwZGZiN2VkMzY3Y2Y3OTdlNTdjNTViOTI2NmIzNGNiNjY4Njc2ZTVkNzdiZDI1MjgwMTg3ZjM1YzNmNjJmZmY5MzE0Y2NjOGFhMmI4MzEzMGJlZDhhZjY3Mzc4MDMxZDBmZDExZDQ4NDc3ZDk2ZjY3YTBiZTQyNzBkMzkwZmZjYWVjYmU0YWU2MjE4Y2I4ZWFjYWViN2M3YzgyZjBiOGU3OTRjMGU2NTFiNWM5YjQ2NmIwNGEwNmVmNThlMzg4ZTNjNmQ4NzZkYjExMWNiZTJmOWRmMGNkMTA4NWI5NGMxZGUxZjJhZGUwMWUxMDY4ZTVjZTI3ZTI2Y2ZlMWI5MTI2NDZlMGNiNGFjMjdiZTFkZTkxYjRlN2U4MjVkNTgyMzFiMDE4N2ZiODRiZTUyN2ZhMDAxZTU4YzkzNTQ3NDM2YzA5NzYzODNhNDA5YzNhMzA0MGYzNzA4ZDM4ZWQzZWM1NDgyZmVlNzJiMjNlYjZmYzk0NjZlZjU1YzVmMDVmZDBiNDkyNWY1NmMyOTY3Yjc0MjAxY2I1YjZjY2E4MWJiMWViODE1ZjUxYTFmZjI5YThjOTk5YWZkZTIyNTZlNDA2ZjhmNTRmZGE1YTBmNzA2OGY1YzY3NWM5OGU0ODQ5M2I1M2I2MmUyYWU5YzkyNmM4NjQ4MmU2M2M4ZmM5NGVhMTVjOTU1OTUxNDdhMzRmNDk1OWZhNjhhMmZkODJkZmQzZjY4ZTBiYWE0NWYxYTRlNDBiN2I0Y2UwZTZkNTc1MDYyZWVkNDQ5ZjM1ODMxOGNlZDkzMzRjODQzNzk0OTE5MDc1NTI4MDU4Yjg0NGVhZDEzMTM0ZjAzYjgxNDRhZWZhNWUwYjUzNTdmNjc3ZWQ5NjIyZjhkZThlNzE3NjJjZTNkYmU3NjUxNzkzMWFkNjJmZGU0YzBiMGViMjJjZjY4NjEwMzBlNWQwNDlhOWU3NTE3ZWFiYTRiMmYwNTE0Mzc2NGNlZGZiZTMyNWY1Zjk1NWQwMTQzZGJkMDkyZWNkMTExYjdhOWIxMTZiNjVjMTc1ZmM1N2EwNDFkMWFjYjExYjIxYWJkZmMzNzVlOWIxMTcyNGQ4YjI0YzYxN2IzNjAwN2ViZGY0OThkYWYxMDJhNTM4MjA0OTIyZDVlYzYwMWRlYjUwZWNiYzViNGEwMmM1YzlkNDc4MzE5ODE3MmJhYmQ2ZDkxYjIyOTFlNTE0YTBlOTJhOTdmNzFlZjYxNjFkNTY3ZGQ2YWY0NTkzZjQ1ZDU3NDQzNGNmNzg1NjY1ZjRlMDM5YjA1ZDY0Y2MxYjkwZjIyMGIwNDYyMTEzNWM4NDc0YjY0ZjY1NTE1ZjZjYjdjMTAyZGVlNDc3OTI2YmY2YzlmM2VlYzNlYzhmOTFhYTIzZSIsImtleV9pZCI6Ijc4YTk1Mzc1ZTMwNDQ4ZTQifQ=='); $_postD = json_decode($_KEYRES, true); $_postD['search'] = $tel; $_postD['user_search'] = ""; $_PHONERES = getKD('https://mhaoma.baidu.com/api/v1/search?appkey=9ef446ebde00e7303b32aca6', json_encode($_postD)); // 蛙蛙的 $_wawaZX = getKD('https://www.iamwawa.cn/home/saoraodianhua/ajax', ['phone' => $tel]); $wawaJson = json_decode($_wawaZX, true)['status'] == '1' ? '骚扰电话' : '正常号码'; $_resJSON = json_decode($_PHONERES, true)['data']; // 搜狗的 $_sougouRes = getSouGouRes($tel); preg_match_all('/vr\((.*?);\}\);/i', $_sougouRes, $_sougouResArr); $__arr = explode(',', str_replace('\'', '', $_sougouResArr[1][0])); $_sougouRes = explode(':', $__arr[4]); $_sougouOr = $_sougouRes[1] ? $_sougouRes[1] . '电话' : '正常号码'; $res_arr = ['success' => true, 'tel' => $tel, 'info' => ['province' => $_resJSON[$tel]['location']['province'], 'city' => $_resJSON[$tel]['location']['area'][0]['city'], 'operator' => $_resJSON[$tel]['location']['operator']], 'data' => [['name' => '360手机卫士', 'msg' => $wawaJson], ['name' => '搜狗号码通', 'msg' => $_sougouOr], ['name' => '百度手机卫士', 'msg' => $_resJSON[$tel]['reports'][0]['id'] ? $_resJSON[$tel]['reports'][0]['name'] : '正常号码']]]; exit(json_encode($res_arr, JSON_UNESCAPED_UNICODE)); function getSouGouRes($tel) { $url = "https://www.sogou.com/web?query={$tel}"; $ip = rand(0, 255) . '.' . rand(0, 255) . '.' . rand(0, 255) . '.' . rand(0, 255); $header[] = "accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"; $header[] = ":authority: www.sogou.com"; $header[] = "accept-language: zh-CN,zh;q=0.9"; $header[] = 'sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="97", "Chromium";v="97"'; $header[] = "upgrade-insecure-requests: 1"; $header[] = "user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"; $header[] = "CLIENT-IP:" . $ip; $header[] = "X-FORWARDED-FOR:" . $ip; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); //设置传输的 url curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //发送 http 报头 curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1"); //设置UA curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 1); //返回response头部信息 curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate'); // 解码压缩文件 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // 对认证证书来源的检查 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // 从证书中检查SSL加密算法是否存在 curl_setopt($ch, CURLOPT_TIMEOUT, 5); // 设置超时限制防止死循环 $output = curl_exec($ch); curl_close($ch); return str_replace(["\n", "\t", "\r", ' '], '', $output); } function getKD($url, $postDDAT) { $ip = rand(0, 255) . '.' . rand(0, 255) . '.' . rand(0, 255) . '.' . rand(0, 255); $header[] = "Accept: */*"; $header[] = "Accept-Encoding: gzip, deflate, br"; $header[] = "Accept-Language: zh-CN,zh;q=0.9"; $header[] = "Connection: keep-alive"; $header[] = "CLIENT-IP:" . $ip; $header[] = "X-FORWARDED-FOR:" . $ip; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); //设置传输的 url curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //发送 http 报头 curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1"); //设置UA curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate'); // 解码压缩文件 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // 对认证证书来源的检查 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // 从证书中检查SSL加密算法是否存在 curl_setopt($ch, CURLOPT_TIMEOUT, 5); // 设置超时限制防止死循环 curl_setopt($ch, CURLOPT_POST, 1); //设置POST发送数据 curl_setopt($ch, CURLOPT_POSTFIELDS, $postDDAT); //发送POST数据内容 $output = curl_exec($ch); curl_close($ch); return $output; }
2022年11月19日
1,951 阅读
6 评论
4 点赞
2022-11-11
蓝奏云盘解析API接口 开源
{message type="info" content="根据 服务器接口数量、带宽、可维护性等多种因素,韩小韩API接口站决定下架蓝奏云解析API接口,不过由于使用量过大,突然下架是对用户的不负责,故将解析接口开源,供大家直接使用或二次修改使用。"/}蓝奏云解析API{abtn icon="fa-link" color="#00b3ff" href="https://api.vvhan.com/lanzou.html" radius="" content="蓝奏云解析 - 韩小韩API"/} 蓝奏云解析API源码<?php header("Access-Control-Allow-Origin:*"); header('Content-type:application/json; charset=utf-8'); // API调用统计 // include './sum/db/apicount.php'; // hansCount("lanzou"); // 取文件地址 (isset($_GET['url']) && $_GET['url']) ? ($uurl = $_GET['url']) : exit(json_encode(["success" => false, "message" => "文件不存在"], JSON_UNESCAPED_UNICODE)); $_url = str_replace(['http://', 'https://'], '', $uurl); // 取文件Key $_keyArr = explode('/', $_url); $_key = end($_keyArr); // 统计基础地址 $BASEURL = 'https://_.lanzouq.com/'; // 统一接口 $_res = getData($BASEURL . $_key); // 取参数 preg_match_all('/user-name">(.*?)<\/span>/i', $_res, $_fileAutherArr); if ($_fileAutherArr[1]) { preg_match_all('/filenajax">(.*?)<\/div>/i', $_res, $_fileNameArr); preg_match_all('/n_file_infos">(.*?)<\/span>/i', $_res, $_fileInfoArr); preg_match_all('/大小:(.*?)<\/div>/i', $_res, $_fileSizeArr); if (count($_fileInfoArr[1]) > 1) { $__time = $_fileInfoArr[1][0]; $__type = $_fileInfoArr[1][1]; } else { $__time = '-'; $__type = $_fileInfoArr[1][0]; } $infoArr = [ 'name' => $_fileNameArr[1][0] ?? '-', 'auther' => $_fileAutherArr[1][0] ?? '-', 'time' => $__time ?? '-', 'size' => $_fileSizeArr[1][0] ?? '-', 'type' => $__type ?? '-' ]; } else { preg_match_all('/<title>(.*?) - 蓝奏云/i', $_res, $fileNameArr); preg_match_all('/span>(.*?)<br/i', $_res, $infoArr); preg_match_all('/font>(.*?)<\/font/i', $_res, $autherArr); $infoArr = [ 'name' => $fileNameArr[1][0] ?? '-', 'auther' => $autherArr[1][0] ?? '-', 'time' => $infoArr[1][1] ?? '-', 'size' => $infoArr[1][0] ?? '-', 'type' => $infoArr[1][3] ?? '-' ]; } // 取二次数据 preg_match_all('/src="(.*?)" frameborder/i', $_res, $ifarmArr); $ifarmUrl = strlen($ifarmArr[1][0]) > 36 ? $ifarmArr[1][0] : $ifarmArr[1][1]; $_sres = getData($BASEURL . $ifarmUrl); // 取键值对 preg_match_all("/'(.*?)'/i", $_sres, $downKeyArr); preg_match_all("/ajaxdata = '(.*?)';/i", $_sres, $ajaxdata); preg_match_all("/websignkey = '(.*?)';/i", $_sres, $webKey); preg_match_all("/wsk_sign = '(.*?)';/i", $_sres, $webKeys); // 取downKey $downKey = ''; foreach ($downKeyArr[1] as $v) { strlen($v) > 36 && ($downKey = $v); } // 取直链 if ($downKey) { $datas = curlPosr($downKey, $ajaxdata[1][0], $webKey[1][0] ?? $webKeys[1][0], $BASEURL); $json = json_decode($datas, true); $result = array("success" => true, 'info' => $infoArr, "download" => $json['dom'] . "/file/" . $json['url'], "fileUrl" => restoreUrl($json['dom'] . "/file/" . $json['url'])); exit(json_encode($result, JSON_UNESCAPED_UNICODE)); } else { $result = array("success" => false, "message" => "文件不存在"); exit(json_encode($result, JSON_UNESCAPED_UNICODE)); } // POST请求封装 function curlPosr($urls, $ajaxData, $webKey, $uname) { $ip = rand(0, 255) . '.' . rand(0, 255) . '.' . rand(0, 255) . '.' . rand(0, 255); $header[] = "CLIENT-IP:" . $ip; $header[] = "X-FORWARDED-FOR:" . $ip; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "{$uname}ajaxm.php"); curl_setopt($ch, CURLOPT_REFERER, $uname . $urls); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //发送 http 报头 curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // POST数据 $data = array( "signs" => $ajaxData, "action" => "downprocess", "sign" => $urls, "websign" => '', "ves" => "1", "websignkey" => $webKey ); curl_setopt($ch, CURLOPT_POST, 1); // 把post的变量加上 curl_setopt($ch, CURLOPT_POSTFIELDS, $data); $output = curl_exec($ch); curl_close($ch); return $output; } // GET请求封装 function getData($url) { $ip = rand(0, 255) . '.' . rand(0, 255) . '.' . rand(0, 255) . '.' . rand(0, 255); $header[] = "accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"; $header[] = "accept-encoding: gzip, deflate, br"; $header[] = "accept-language: zh-CN,zh;q=0.9"; $header[] = "cache-control: max-age=0"; $header[] = "sec-ch-ua: \"Google Chrome\";v=\"95\", \"Chromium\";v=\"95\", \";Not A Brand\";v=\"99\""; $header[] = "sec-ch-ua-mobile: ?0"; $header[] = "sec-ch-ua-platform: \"Windows\""; $header[] = "sec-fetch-dest: document"; $header[] = "CLIENT-IP:" . $ip; $header[] = "X-FORWARDED-FOR:" . $ip; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); //设置传输的 url // curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //发送 http 报头 curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36"); //设置UA curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate'); // 解码压缩文件 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // 对认证证书来源的检查 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // 从证书中检查SSL加密算法是否存在 curl_setopt($ch, CURLOPT_TIMEOUT, 5); // 设置超时限制防止死循环 $output = curl_exec($ch); curl_close($ch); return $output; } // 连接转换封装 function restoreUrl($shortUrl) { $ip = rand(0, 255) . '.' . rand(0, 255) . '.' . rand(0, 255) . '.' . rand(0, 255); $header[] = "accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"; $header[] = "accept-encoding: gzip, deflate, br"; $header[] = "accept-language: zh-CN,zh;q=0.9"; $header[] = "cache-control: max-age=0"; $header[] = "sec-ch-ua: \"Google Chrome\";v=\"95\", \"Chromium\";v=\"95\", \";Not A Brand\";v=\"99\""; $header[] = "sec-ch-ua-mobile: ?0"; $header[] = "sec-ch-ua-platform: \"Windows\""; $header[] = "sec-fetch-dest: document"; $header[] = "CLIENT-IP:" . $ip; $header[] = "X-FORWARDED-FOR:" . $ip; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $shortUrl); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36"); //设置UA curl_setopt($ch, CURLOPT_NOBODY, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_exec($ch); $info = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); curl_close($ch); return $info; }{callout color="#f0ad4e"}蓝奏云解析 - 到此结束。{/callout}
2022年11月11日
1,876 阅读
5 评论
7 点赞
2022-11-02
知乎热榜API、百度热点API、微博热搜API(开源)- 聚合热榜API开源
{message type="info" content="源码为一次源码,源接口为官方接口,与 韩小韩API(Api.Vvhan.Com)使用接口完全相同,上传即用!"/}环境需求PHP 5.4及以上使用方式:上传即用知乎热榜API源码<?php // 知乎热榜 热度 function zhihuHot() { $_resHtml = str_replace(["\n", "\r", " "], '', vvhanCurl('https://www.zhihu.com/hot', ['User-Agent:Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'], 'https://www.zhihu.com')); preg_match('/<scriptid=\"js-initialData\"type=\"text\/json\">(.*?)<\/script>/', $_resHtml, $_resHtmlArr); $jsonRes = json_decode($_resHtmlArr[1], true); $tempArr = []; foreach ($jsonRes['initialState']['topstory']['hotList'] as $k => $v) { array_push($tempArr, [ 'index' => $k + 1, 'title' => $v['target']['titleArea']['text'], 'desc' => $v['target']['excerptArea']['text'], 'pic' => $v['target']['imageArea']['url'], 'hot' => $v['target']['metricsArea']['text'], 'url' => $v['target']['link']['url'], 'mobilUrl' => $v['target']['link']['url'] ]); } return [ 'success' => true, 'title' => '知乎热榜', 'subtitle' => '热度', 'update_time' => date('Y-m-d h:i:s', time()), 'data' => $tempArr ]; } ?>百度热点API源码<?php // 百度热点 指数 function baiduredian() { $_resHtml = str_replace(["\n", "\r", " "], '', vvhanCurl('https://top.baidu.com/board?tab=realtime', null)); preg_match('/<!--s-data:(.*?)-->/', $_resHtml, $_resHtmlArr); $jsonRes = json_decode($_resHtmlArr[1], true); return $jsonRes; $tempArr = []; foreach ($jsonRes['data']['cards'] as $v) { foreach ($v['content'] as $k => $_v) { array_push($tempArr, [ 'index' => $k + 1, 'title' => $_v['word'], 'desc' => $_v['desc'], 'pic' => $_v['img'], 'url' => $_v['url'], 'hot' => $_v['hotScore'] . 'W个内容', 'mobilUrl' => $_v['appUrl'] ]); } } return [ 'success' => true, 'title' => '百度热点', 'subtitle' => '指数', 'update_time' => date('Y-m-d h:i:s', time()), 'data' => $tempArr ]; } ?>微博热搜API源码<?php // 微博 热搜榜 function wbresou() { $_md5 = md5(time()); $cookie = "Cookie: {$_md5}:FG=1"; $jsonRes = json_decode(vvhanCurl('https://weibo.com/ajax/side/hotSearch', null, $cookie, "https://s.weibo.com"), true); $tempArr = []; foreach ($jsonRes['data']['realtime'] as $k => $v) { array_push($tempArr, [ 'index' => $k + 1, 'title' => $v['note'], 'hot' => $v['num'] . '万', 'url' => "https://s.weibo.com/weibo?q={$v['word_scheme']}&t=31&band_rank=12&Refer=top", 'mobilUrl' => "https://s.weibo.com/weibo?q={$v['word_scheme']}&t=31&band_rank=12&Refer=top" ]); } return [ 'success' => true, 'title' => '微博', 'subtitle' => '热搜榜', 'update_time' => date('Y-m-d h:i:s', time()), 'data' => $tempArr ]; } ?>三合一聚合源码{callout color="#f0ad4e"}知乎热榜、百度热点、微博热搜 API三合一聚合源码{/callout}<?php /* * @Author: Han * @Date: 2022-11-02 13:45:21 * @LastEditors: Han * @LastEditTime: 2022-11-02 13:52:21 * @FilePath: \WWW\hotlist.php * @NetWork: 韩小韩博客 www.vvhan.com */ error_reporting(0); header("Access-Control-Allow-Origin:*"); header("Content-type:application/json; charset=utf-8"); date_default_timezone_set("Asia/Shanghai"); class VvhanApi { // 知乎热榜 热度 public function zhihuHot() { $_resHtml = str_replace(["\n", "\r", " "], '', $this->vvhanCurl('https://www.zhihu.com/hot', ['User-Agent:Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'], 'https://www.zhihu.com')); preg_match('/<scriptid=\"js-initialData\"type=\"text\/json\">(.*?)<\/script>/', $_resHtml, $_resHtmlArr); $jsonRes = json_decode($_resHtmlArr[1], true); $tempArr = []; foreach ($jsonRes['initialState']['topstory']['hotList'] as $k => $v) { array_push($tempArr, [ 'index' => $k + 1, 'title' => $v['target']['titleArea']['text'], 'desc' => $v['target']['excerptArea']['text'], 'pic' => $v['target']['imageArea']['url'], 'hot' => $v['target']['metricsArea']['text'], 'url' => $v['target']['link']['url'], 'mobilUrl' => $v['target']['link']['url'] ]); } return [ 'success' => true, 'title' => '知乎热榜', 'subtitle' => '热度', 'update_time' => date('Y-m-d h:i:s', time()), 'data' => $tempArr ]; } // 微博 热搜榜 public function wbresou() { $_md5 = md5(time()); $cookie = "Cookie: {$_md5}:FG=1"; $jsonRes = json_decode($this->vvhanCurl('https://weibo.com/ajax/side/hotSearch', null, $cookie, "https://s.weibo.com"), true); $tempArr = []; foreach ($jsonRes['data']['realtime'] as $k => $v) { array_push($tempArr, [ 'index' => $k + 1, 'title' => $v['note'], 'hot' => $v['num'] . '万', 'url' => "https://s.weibo.com/weibo?q={$v['word_scheme']}&t=31&band_rank=12&Refer=top", 'mobilUrl' => "https://s.weibo.com/weibo?q={$v['word_scheme']}&t=31&band_rank=12&Refer=top" ]); } return [ 'success' => true, 'title' => '微博', 'subtitle' => '热搜榜', 'update_time' => date('Y-m-d h:i:s', time()), 'data' => $tempArr ]; } // 百度热点 指数 public function baiduredian() { $_resHtml = str_replace(["\n", "\r", " "], '', $this->vvhanCurl('https://top.baidu.com/board?tab=realtime', null)); preg_match('/<!--s-data:(.*?)-->/', $_resHtml, $_resHtmlArr); $jsonRes = json_decode($_resHtmlArr[1], true); return $jsonRes; $tempArr = []; foreach ($jsonRes['data']['cards'] as $v) { foreach ($v['content'] as $k => $_v) { array_push($tempArr, [ 'index' => $k + 1, 'title' => $_v['word'], 'desc' => $_v['desc'], 'pic' => $_v['img'], 'url' => $_v['url'], 'hot' => $_v['hotScore'] . 'W个内容', 'mobilUrl' => $_v['appUrl'] ]); } } return [ 'success' => true, 'title' => '百度热点', 'subtitle' => '指数', 'update_time' => date('Y-m-d h:i:s', time()), 'data' => $tempArr ]; } private function vvhanCurl($url, $header = [ "accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "Accept-Encoding: gzip, deflate, br", "Accept-Language: zh-CN,zh;q=0.9", "Connection: keep-alive", "User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1" ], $cookie = null, $refer = 'https://www.baidu.com') { $ip = rand(0, 255) . '.' . rand(0, 255) . '.' . rand(0, 255) . '.' . rand(0, 255); $header[] = "CLIENT-IP:" . $ip; $header[] = "X-FORWARDED-FOR:" . $ip; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); //设置传输的 url curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //发送 http 报头 curl_setopt($ch, CURLOPT_COOKIE, $cookie); //设置Cookie curl_setopt($ch, CURLOPT_REFERER, $refer); //设置Referer curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate'); // 解码压缩文件 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // 对认证证书来源的检查 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // 从证书中检查SSL加密算法是否存在 curl_setopt($ch, CURLOPT_TIMEOUT, 5); // 设置超时限制防止死循环 $output = curl_exec($ch); curl_close($ch); return $output; } } $_type = isset($_GET['type']) ? $_GET['type'] : ''; $API = new VvhanApi; switch ($_type) { case 'baidu': $_res = $API->baiduredian(); break; case 'zhihu': $_res = $API->zhihuHot(); break; case 'weibo': $_res = $API->wbresou(); break; default: $_res = ['success' => false, 'message' => '参数不完整']; break; } $_res['copyright'] = '韩小韩博客 www.vvhan.com'; exit(json_encode($_res, JSON_UNESCAPED_UNICODE)); ?>成品使用{callout color="#f0ad4e"}如果你懒得搭建,可使用 韩小韩API(Api.Vvhan.Com)提供的 聚合热榜API{/callout}{abtn icon="fa-link" color="#4eda9d" href="https://api.vvhan.com/hotlist.html" radius="" content="热榜热搜各站热榜聚合API"/}
2022年11月02日
2,123 阅读
11 评论
1 点赞
2022-10-21
chrome闭包断点
{callout color="#f0ad4e"}首先呢,必须搞清楚闭包这个概念:闭包其实是一个特殊的对象,他由两部分组成,一个是执行上下文(代号A),以及在该执行上下文中创建的函数(代号B),当B执行时,如果访问了A中变量对象的变量,那么闭包就产生了。{/callout}下面这个例子会产生闭包function add(x) { return function _add(y){ return x + y } } var sum = add(2)(3){callout color="#f0ad4e"}上面这个例子毫无疑问肯定是 5那么使用chrome浏览器单步调试一下将断点打到 var sum = add(2)(3) 这里{/callout}Brealpoints 表示当前打的断点是什么CallStack 表示当前函数调用栈Scope 表示当前作用域Scope 里面的 Local 表示当前活动对象Scope 里面的 Closure 表示闭包{callout color="#f0ad4e"}图上一直点击红色箭头所指按钮表示单点调试,代码一步一步执行,等执行到return那里的时候,右侧 Scope 里会多出一个 Closure 属性,括号内的add表示当前闭包函数是add,闭包产生的值是 x = 2有时候调试会发现没有这个 Closure 属性,例如下面这个例子{/callout}const obj = { name: '我是需要被绑定改变this指向的对象' } function fn() Function.prototype.bind = function (sbbbbb) { const bind = Symbol(); sbbbbb[bind] = this return function () { sbbbbb[bind](); } } fn.bind(obj);这个例子是 bind 改变 this 指向的实现方式,将断点打向 fn.bind(obj) 接着看动态图{callout color="#f0ad4e"}在动画的过程中,当走到 sbbbbb[bind]() 的时候,Local 里面会多出一个 Return value: ƒ () 的属性,展开这个属性,会发现有个 [[Scopes]] 的属性,接着展开 [[Scopes]],里面有个 Closure (Function.bind) {sbbbbb: {…}, bind: Symbol()} 就表示当前产生的闭包{/callout}
2022年10月21日
266 阅读
0 评论
0 点赞
2022-10-12
原型继承和 Class 继承
⾸先先来讲下 class ,其实在 JS 中并不存在类, class 只是语法糖,本质还是函数class Person {} Person instanceof Function // true组合继承function Parent(value) { this.val = value } Parent.prototype.getValue = function() { console.log(this.val) } function Child(value) { Parent.call(this, value) } Child.prototype = new Parent() const child = new Child(1) child.getValue() // 1 child instanceof Parent // true{callout color="#684def"}以上继承的⽅式核⼼是在⼦类的构造函数中通过 Parent.call(this) 继承⽗类的属性,然后改变⼦类的原型为 new Parent() 来继承⽗类的函数。这种继承⽅式优点在于构造函数可以传参,不会与⽗类引⽤属性共享,可以复⽤⽗类的函数,但是也存在⼀个缺点就是在继承⽗类函数的时候调⽤了⽗类构造函数,导致⼦类的原型上多了不需要的⽗类属性,存在内存上的浪费{/callout}寄⽣组合继承{callout color="#4defb9"}这种继承⽅式对组合继承进⾏了优化,组合继承缺点在于继承⽗类函数时调⽤了构造函数,我们只需要优化掉这点就⾏了{/callout}function Parent(value) { this.val = value } Parent.prototype.getValue = function() { console.log(this.val) } function Child(value) { Parent.call(this, value) } Child.prototype = Object.create(Parent.prototype, { constructor: { value: Child, enumerable: false, writable: true, configurable: true } }) const child = new Child(1) child.getValue() // 1 child instanceof Parent // trueclass继承class Parent { constructor(value) { this.val = value } getValue() { console.log(this.val) } } class Child extends Parent { constructor(value) { super(value) this.val = value } } let child = new Child(1) child.getValue() // 1 child instanceof Parent // true
2022年10月12日
455 阅读
0 评论
0 点赞
2022-10-04
DOM同级传递事件
{callout color="#f0ad4e"}大家到现在所了解到的事件,基本都离不开浏览器的行为。比如点击鼠标、按下键盘等等,这些都可以被浏览器感知到,进而帮助我们转换成一个“信号”触发对应处理函数。但是还有一些行为,是浏览器感知不到的。比如说看这样一段 html{/callout}<div class="a"></div> <div class="b"></div> <div class="c"></div>如果我们仅仅想监听 a 这个元素上的点击行为,我们可以用 addEventListener 来安装监听函数var a = document.getElementById('a') document.addEventListener('click',function(){ console.log('a') })但是,如果现在想实现这样一种效果在点击A之后,B 和 C 都能感知到 A 被点击了,并且做出相应的行为——就像这个点击事件是点在 B 和 C 上一样。我们知道,借助时间捕获和冒泡的特性,我们是可以实现父子元素之间的行为联动的。但是此处,A、B、C三者位于同一层级,他们怎么相互感知对方身上发生了什么事情呢?“A被点击了”这件事情,可以作为一个事件来派发出去,由 B 和 C 来监听这个事件,并执行各自身上安装的对应的处理函数。在这个思路里,“A被点击了”这个动作挺特别,特别就特别在浏览器不认识它。因为浏览器不认识它,所以浏览器不肯”帮忙“,不会帮咱去感知和派发这个动作。不过没关系,感知和派发,咱都可以自己来实现首先大家需要了解的是,自定义事件的创建。比如说咱们要创建一个本来不存在的"clickA"事件,来表示 A 被点击了,可以这么写<div class="a"></div> <div class="b"></div> <div class="c"></div> <script> /* 获取元素 */ const a = document.querySelector(".a") const b = document.querySelector(".b") const c = document.querySelector(".c") /* 创建一个自定义事件 */ const aEvent = new Event("sb250") a.addEventListener("click", function (e) { console.log('a'); /* 派发给b和c */ b.dispatchEvent(aEvent) c.dispatchEvent(aEvent) }) /* b监听 */ b.addEventListener("sb250", function (e) { console.log('b') }) c.addEventListener("sb250", function (e) { console.log('c') }) </script>{callout color="#8e4def"}可以看到,浏览器控制台能正确的打印 a b c,因此实现了对a点击事件的监听{/callout}
2022年10月04日
439 阅读
0 评论
0 点赞
1
...
3
4
5
...
33