PHP对接企业微信
前言
最近在做项目中,要求在后台管理中有企业微信管理的相关功能。相关准备工作,需要准备好企业微信账号,添加自建应用,获得相应功能的权限,以及agentid、secre等。
参考文档:
企业微信开发文档
功能实现
因功能接口比较多,这里以“客户敏感词”为例,以下为“敏感词”管理功能实现。
1 想法思路
企业微信接口有请求次数限制,后台操作频繁,避免多次请求企业微信接口,也为了相应速度考虑,我这里考虑将输入进行入库处理。每次新建敏感词,企业微信“新增敏感词”接口请求成功后,将数据添加到数据库,编辑和删除同理。这样敏感词列表、查看敏感词就可以减少对企业微信接口的请求。
2 注意事项
(1)敏感词这里需要依赖通讯录中的成员和部门,因此需要先开发这两个模块之后,再进行敏感词功能开发(成员和部门也做了入库处理,所以在下面代码中,我也是直接查询数据库的内容);
(2)access_token 有三种:通讯录access_token、联系人access_token以及自建应用 access_token,要根据接口需要,看需要哪一种access_token,否则就会报错。敏感词这里使用的是自建应用 access_token。
(3)要记得添加IP白名单。
3 代码实现
InterceptController.php
<?php
// +-----------------------xiaozhe-----------------------------------------------namespace app\wework\controller;use cmf\controller\AdminBaseController;
use app\wework\service\InterceptService;
use app\wework\service\WechatInterceptApi;
use app\wework\model\InterceptModel;
use app\wework\model\WeUserModel;
use app\admin\model\AdminMenuModel;class InterceptController extends AdminBaseController
{// 敏感词列表public function index(){ // 接口请求敏感词列表// $wxinterceptApi = new WechatInterceptApi();// $list = $wxinterceptApi->getInterceptRuleList();// echo "<pre>";// print_r($list);// exit;$param = $this->request->param();$interceptService = new InterceptService();$data = $interceptService->getList($param);$data->appends($param);$this->assign('keyword', isset($param['keyword']) ? $param['keyword'] : '');$this->assign('lists', $data->items());$this->assign('page', $data->render());return $this->fetch();}// 新增敏感词public function add(){if ($this->request->isPost()) {$data = $this->request->param();$interceptModel = new InterceptModel();$data['create_time'] = time();$data['user_id'] = cmf_get_current_admin_id();$data['group_id'] = 0;if ($data['applicable_type'] == 2) {// 选择员工的话,是员工名$userModel = new WeUserModel();$userList = $userModel->whereIn('userid',$data['applicable_range'])->column("userid","department_id");$group_arr = array_unique(array_keys($userList));$applicable_range['user_list'] = implode(",",$userList);$applicable_range['department_list'] = implode(",",$group_arr);$data['applicable_range'] = json_encode($applicable_range,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);} else {$userModel = new WeUserModel();$userList = $userModel->whereIn('department_id',$data['applicable_range'])->column("userid");$applicable_range['user_list'] = implode(",",$userList);$applicable_range['department_list'] = $data['applicable_range'];$data['applicable_range'] = json_encode($applicable_range,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);}if (!empty($data['semantics_list'])) {$data['semantics_list'] = implode(",",$data['semantics_list']);}// 敏感词接口新增$user_list = !empty($applicable_range['user_list']) ? explode(",",$applicable_range['user_list']) : [];$department_list = explode(",",$applicable_range['department_list']);$wx_intercept = array('rule_name' => $data['rule_name'],'word_list' => explode(",",$data['word_list']),'semantics_list' => explode(",",$data['semantics_list']),'intercept_type' => $data['intercept_type'],'applicable_range' => array('user_list' => $user_list,'department_list' => $department_list));$wxinterceptApi = new WechatInterceptApi();$res = $wxinterceptApi->addInterceptRule($wx_intercept);if ($res['errcode'] != 0) {$this->error($res['errmsg'], url("Intercept/index"));}$data['rule_id'] = $res['rule_id'];$result = $interceptModel->save($data);if ($result) {$this->success('添加成功!', url("Intercept/index"));} else {$this->error('添加失败!', url("Intercept/index"));}}return $this->fetch();}// 编辑敏感词public function edit(){if ($this->request->isPost()) {$data = $this->request->param();$id = $data['id'] ?? 0;unset($data['id']);if ($data['applicable_type'] == 2) {// 选择员工的话,是员工名$userModel = new WeUserModel();$userList = $userModel->whereIn('userid',$data['applicable_range'])->column("userid","department_id");$group_arr = array_unique(array_keys($userList));$applicable_range['user_list'] = implode(",",$userList);$applicable_range['department_list'] = implode(",",$group_arr);$data['applicable_range'] = json_encode($applicable_range,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);} else {$userModel = new WeUserModel();$userList = $userModel->whereIn('department_id',$data['applicable_range'])->column("userid");$applicable_range['user_list'] = implode(",",$userList);$applicable_range['department_list'] = $data['applicable_range'];$data['applicable_range'] = json_encode($applicable_range,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);}$update_info = $data;$interceptModel = new InterceptModel();// 敏感词接口编辑// 查询原来的数据$rule_info = $interceptModel->field("rule_id,applicable_range")->where("id",$id)->find();$old_add_applicable_range = json_decode($rule_info['applicable_range'],true);$old_user_list = !empty($old_add_applicable_range['user_list']) ? explode(",",$old_add_applicable_range['user_list']) : [];$old_department_list = !empty($old_add_applicable_range['department_list']) ? explode(",",$old_add_applicable_range['department_list']) : [];$user_list = !empty($applicable_range['user_list']) ? explode(",",$applicable_range['user_list']) : [];$department_list = explode(",",$applicable_range['department_list']);$wx_intercept = array('rule_id' => $rule_info['rule_id'],'rule_name' => $update_info['rule_name'],'word_list' => explode(",",$update_info['word_list']),'extra_rule' => array('semantics_list' => $data['semantics_list'],),'intercept_type' => $data['intercept_type'],'add_applicable_range' => array('user_list' => $user_list,'department_list' => $department_list),'remove_applicable_range' => array('user_list' => $old_user_list,'department_list' => $old_department_list));$wxinterceptApi = new WechatInterceptApi();$res = $wxinterceptApi->updateInterceptRule($wx_intercept);if ($res['errcode'] != 0) {$this->error($res['errmsg'], url("Intercept/index"));}if (!empty($update_info['semantics_list'])) {$update_info['semantics_list'] = implode(",",$update_info['semantics_list']);}$result = $interceptModel->where("id",$id)->update($update_info);if ($result) {$this->success('编辑成功!', url("Intercept/index"));} else {$this->error('编辑失败!', url("Intercept/index"));}}$id = $this->request->param('id', 0, 'intval');if (empty($id)) {$this->error('请求参数有误!');}// 查询敏感词信息$interceptService = new InterceptService();$info = $interceptService->getInfo($id);// 接口请求敏感词详情// $wxinterceptApi = new WechatInterceptApi();// $list = $wxinterceptApi->getInterceptRuleInfo(['rule_id'=>$info['rule_id']]);// echo "<pre>";// print_r($list);// exit;$this->assign('info',$info);return $this->fetch();}// 删除敏感词public function delete(){$param = $this->request->param();$interceptModel = new InterceptModel();if (isset($param['id'])) {$id = $this->request->param('id', 0, 'intval');$rule_info = $interceptModel->field("rule_id")->where("id",$id)->find();$wxinterceptApi = new WechatInterceptApi();$wx_res = $wxinterceptApi->deleteInterceptRule(['rule_id'=>$rule_info['rule_id']]);if ($wx_res['errcode'] == 0) {$result = $interceptModel->where('id', $id)->delete();$this->success("删除成功!");} else {$this->error("删除失败!");}}}public function checkWorker(){$param = $this->request->param();$applicable_type = $param['type'] ?? 1;$applicable_range = $param['value'] ?? "";$interceptService = new InterceptService();$result = $interceptService->getWorkerList($param);$this->assign('menus', $result);$this->assign('applicable_range', explode(",",$applicable_range));$this->assign('applicable_type',$applicable_type);return $this->fetch();}}
InterceptService.php
<?php
// +----------------------------------------------------------------------
// xiaozhe
// +----------------------------------------------------------------------
namespace app\wework\service;use app\wework\model\InterceptModel;
use app\wework\model\DepartModel;
use app\wework\model\WeUserModel;
use think\db\Query;class InterceptService
{public function getList($filter){$field = 'a.id,a.rule_name,a.word_list,a.intercept_type,a.applicable_type,a.user_id,a.create_time,a.update_time,u.user_nickname';$interceptModel = new InterceptModel();$result = $interceptModel->alias("a")->leftJoin("user u","a.user_id = u.id")->field($field)->where(function (Query $query) use ($filter) {$keyword = empty($filter['keyword']) ? '' : $filter['keyword'];if (!empty($keyword)) {$query->where('a.title', 'like', "%$keyword%");}})->paginate(15);return $result;}public function getInfo($id){$interceptModel = new InterceptModel();$info = $interceptModel->where("id",$id)->find();if (!empty($info['semantics_list'])) {$info['semantics_list'] = explode(",",$info['semantics_list']);}if (!empty($info['applicable_range'])) {$info['applicable_range'] = json_decode($info['applicable_range'],true);$info['user_count'] = count(explode(",",$info['applicable_range']['user_list']));$info['depart_count'] = count(explode(",",$info['applicable_range']['department_list']));if ($info['applicable_type'] == 1) {// 部门$info['applicable_range_value'] = $info['applicable_range']['department_list'];} else {// 员工$userModel = new WeUserModel();$userIds = $userModel->whereIn("userid",$info['applicable_range']['user_list'])->whereIn("department_id",$info['applicable_range']['department_list'])->column("userid");$info['applicable_range_value'] = implode(",",$userIds);}}return $info;}public function getWorkerList($filter){$type = $filter['type'];switch ($type) {case 1:// 部门$departmentModel = new DepartModel();$newList = $departmentModel->field("department_id as id,name,parentid as parent_id")->select()->toArray();break;case 2:// 员工$userModel = new WeUserModel();$newList = $userModel->field("userid as id,name")->select()->toArray();break;default:// code...break;}return $newList;}}
WechatInterceptApi.php
<?php
// +----------------------------------------------------------------------
// | xiaozhe
// +----------------------------------------------------------------------
namespace app\wework\service;
use app\wework\model\ConfigModel;
use think\Db;
/**
* 企业微信接口
**/
class WechatInterceptApi
{/*** 获取通讯录access_token**/public function getStaffAccessToken(){$cache_key = 'staff_access_token';$res = cache($cache_key);if(empty($res)){// 读取配置$WeworkConfigModel = new ConfigModel();$info = $WeworkConfigModel->where("id",1)->find();$response = cmf_curl_get("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={$info['corpid']}&corpsecret={$info['user_secret']}");$arr = json_decode($response, true); if($arr['errcode'] !== 0){return '';}cache($cache_key, $arr['access_token'], 6900);}return $res;}/*** 获取客户联系人access_token**/static public function getCustomerAccessToken(){$cache_key = 'customer_access_token';$res = cache($cache_key);if(empty($res)){$WeworkConfigModel = new ConfigModel();$info = $WeworkConfigModel->where("id",1)->find();$response = cmf_curl_get("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={$info['corpid']}&corpsecret={$info['customer_secret']}");$arr = json_decode($response, true); if($arr['errcode'] !== 0){return '';}cache($cache_key, $arr['access_token'], 6900);}return $res;}/*** 获取自建应用 access_token**/public function getSelfappAccessToken(){$cache_key = 'selfapp_access_token';$res = cache($cache_key);if(empty($res)){$WeworkConfigModel = new ConfigModel();$info = $WeworkConfigModel->where("id",1)->find();$response = cmf_curl_get("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={$info['corpid']}&corpsecret={$info['corpsecret']}");$arr = json_decode($response, true); if($arr['errcode'] !== 0){return '';}cache($cache_key, $arr['access_token'], 6900);}return $res;}// 获取敏感词列表public function getInterceptRuleList(){$token = self::getSelfappAccessToken();$res = cmf_curl_get("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_intercept_rule_list?access_token=".$token,array());$resp_arr = json_decode($res, 1);return $resp_arr;}// 新增敏感词public function addInterceptRule($filter){$token = self::getSelfappAccessToken();$res = self::curl_post("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_intercept_rule?access_token=".$token,json_encode($filter));$resp_arr = json_decode($res, 1);return $resp_arr;}// 获取敏感词详情public function getInterceptRuleInfo($filter){$token = self::getSelfappAccessToken();$res = self::curl_post("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_intercept_rule?access_token=".$token,json_encode($filter));$resp_arr = json_decode($res, 1);return $resp_arr;}// 修改敏感词规则public function updateInterceptRule($filter){$token = self::getSelfappAccessToken();$res = self::curl_post("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/update_intercept_rule?access_token=".$token,json_encode($filter));$resp_arr = json_decode($res, 1);return $resp_arr;}// 删除敏感词public function deleteInterceptRule($filter){$token = self::getSelfappAccessToken();$res = self::curl_post("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_intercept_rule?access_token=".$token,json_encode($filter));$resp_arr = json_decode($res, 1);return $resp_arr;}public function curl_post($url,$data){$curl = curl_init(); // 启动一个CURL会话curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); // 从证书中检查SSL加密算法是否存在curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referercurl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求curl_setopt($curl, CURLOPT_POSTFIELDS,$data); // Post提交的数据包curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回$result = curl_exec($curl); // 执行操作return $result;}
}
(前端代码我就不放了哈,自行写一哈)
实现效果
敏感词列表
新增敏感词
编辑敏感词
相关文章:

PHP对接企业微信
前言 最近在做项目中,要求在后台管理中有企业微信管理的相关功能。相关准备工作,需要准备好企业微信账号,添加自建应用,获得相应功能的权限,以及agentid、secre等。 参考文档: 企业微信开发文档 功能实现 因…...
【原创】录剪视频的折腾之路
制作视频的起因 本人为IT男,IT发展快,需要学习的东西又多。往往为了一个技术小问题,花好几天时间学习,接下来十来分钟把事情做完。下次遇到这个同样的问题的时候,可能是几个月后,甚至是几年以后了。这些技…...

【BI】FineBI功能学习路径-20231211
FineBI功能学习路径 https://help.fanruan.com/finebi/doc-view-1757.html 编辑数据概述 1.1 调整数据结构 1.2 简化数据 2.1上下合并 2.2其他表添加列 2.3左右合并 新增分析指标 函数参考 https://help.fanruan.com/finereport/doc-view-1897.html 数值函数 日期函数 文…...
pytorch之torch.utils.data学习
1、概述 PyTorch 数据加载利用的核心是torch.utils.data.DataLoader类 。它表示在数据集上 Python 可迭代,支持 map-style and iterable-style datasets(地图样式和可迭代样式数据集), customizing data loading orderÿ…...
Spring Boot 3中一套可以直接用于生产环境的Log4J2日志配置
文章目录 一 Log4J2 相关概念及基本特点二 Spring Boot3 中启用Log4J2的pom.xml配置三 application.properties 的配置四 完整配置 一 Log4J2 相关概念及基本特点 Log4J2是Apache Log4j的升级版,参考了logback的一些优秀的设计,并且修复了一些问题&…...

iOS按钮控件UIButton使用
1.在故事板中添加按钮控件,步聚如下: 同时按钮Shift+Commad+L在出现在控件库中选择Button并拖入View Controller Scene中 将控件与变量btnSelect关联 关联后空心变实心 如何关联?直接到属性窗口拖按钮变量到控件上,出现一条线,然后松开,这样就关联成功了 关联成功后属性窗口…...

小程序开发实战案例之三 | 小程序底部导航栏如何设置
小程序中最常见的功能就是底部导航栏了,今天就来看一下怎么设置一个好看的导航栏~这里我们使用的是支付宝官方小程序 IDE 做示范。 官方提供的底部导航栏 第一步:页面创建 一般的小程序会有四个 tab,我们这次也是配置四个 tab 的…...
Android : 序列化 JSON简单应用
1. JSON介绍 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于阅读和写入,同时也易于机器解析和生成。它基于JavaScript的子集,采用完全独立于语言的文本格式来存储和表示数据。JSON是纯文本&#x…...
Java小案例-RocketMQ的11种消息类型,你知道几种?(普通消息和批量消息)
前言 这篇给大家讲普通消息和批量消息,主要配合代码进行讲解,关于RocketMQ的基础知识已经在上篇给大家讲过需要回顾的点击下面这个链接去看 RocketMQ基础知识 普通消息 普通消息其实就很简单,是Apache RocketMQ中最基础的消息形式&#x…...
前端小技巧: 设计一个简版前端统计 SDK
统计 sdk 如何设计 1 ) 概述 客户端一个sdk ,把数据发送给服务端(第三方统计平台)服务端产生一个统计的报表 2 )需求点 访问量:pv自定义事件:用户的一切行为我们都可以自定义采集性能,错误 3 ) 代码实现 const P…...
DevOps搭建(十一)-Jenkins容器内部使用Docker详解
1、目的 配置的目的是使得Jenkins容器可以直接使用宿主机的Docker,从而可以直接使用Docker命令进行本地打包操作,然后推送到Harbor镜像仓库。 2、修改数据卷 如何在docker中执行宿主机的docker操作,我们管它叫docker in docker。 至于为什么要在docker中操作宿主机的doc…...

用户访问认证
注解 Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) Documented public interface Login { }自定义拦截器 Component public class AuthInterceptor implements HandlerInterceptor {ResourceJwtUtils jwtUtils;Overridepublic boolean preHandle(HttpServ…...
前端知识(七)———HTTPS:保护网络通信安全的关键
当谈到网络通信和数据传输时,安全性是一个至关重要的问题。在互联网上,有许多敏感信息需要通过网络进行传输,例如个人身份信息、银行账户信息和商业机密等。为了保护这些信息不被未经授权的人访问和篡改,HTTPS(超文本传…...
element-ui按钮el-button,点击之后恢复之前的颜色
在开发过程中, 使用el-button 按钮点击之后, 没有恢复到之前的颜色, 还是保持点击之后的颜色,需要解决这个问题, <template><div><el-button size"mini" type"primary" plain click"onClick($event)">按钮</el-button>…...

Excel: Python 如何干掉 VBA 系列 乙
以下内容为本人的学习笔记,如需要转载,请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/k2XtfXS3GUt4r2QhizMOVg 创建工作表格 创建表格 xlwings 就可以协助创建插入了宏的 excel 表格。 先找到一个心满意足的目录,一般我…...

算法笔记—链表、队列和栈
链表、队列和栈 1. 链表1.1 单链表反转1.2 双链表反转1.3 合并两个有序链表1.4 链表相加1.5 划分链表 2. 队列和栈2.1 循环队列2.2 栈实现队列2.3 队列实现栈2.4 最小栈2.2 双端队列 1. 链表 1.1 单链表反转 力扣 反转链表 // 反转单链表public ListNode reverseList(ListNod…...

MySQL中的时间函数整理汇总
1.获取当前时间 -- 获取当前时间 SELECT NOW(); -- 获取当前日期 SELECT CURDATE(); -- 获取当前时分秒 SELECT CURTIME(); 2.获取对应日期对应的年/月/日/月份名/星期数 -- 返回对应日期对应的年/月/日/月份名/星期数 select year(now())as 年,month(now())as 月,day(now())…...

stu06-VSCode里的常用快捷键
Alt Z:文字自动换行。当一行的文字太长时,可以使用。或者查看→自动换行Alt Shift ↓ :快速复制当前行到下一行Alt Shift ↑ :快速复制当前行到上一行Alt B:在默认浏览器中打开当前.html文件Ctrl Enter…...

Bypass open_basedir
讲解 open_basedir是php.ini中的一个配置选项,可用于将用户访问文件的活动范围限制在指定的区域。 假设open_basedir/var/www/html/web1/:/tmp/,那么通过web1访问服务器的用户就无法获取服务器上除了/var/www/html/web1/和/tmp/这两个目录以外的文件。…...
【数据库设计和SQL基础语法】--查询数据--过滤
一、过滤数据 1.1 WHERE子句 基本条件过滤 使用比较运算符 在SQL中,基本条件过滤是通过使用比较运算符来限定检索的数据。以下是一些常用的比较运算符和它们的用法: 运算符说明示例等于 ()用于检索列中与指定值相等的行。示例:SELECT * FROM…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...

Unity VR/MR开发-VR开发与传统3D开发的差异
视频讲解链接:【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...
规则与人性的天平——由高考迟到事件引发的思考
当那位身着校服的考生在考场关闭1分钟后狂奔而至,他涨红的脸上写满绝望。铁门内秒针划过的弧度,成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定",构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...

路由基础-路由表
本篇将会向读者介绍路由的基本概念。 前言 在一个典型的数据通信网络中,往往存在多个不同的IP网段,数据在不同的IP网段之间交互是需要借助三层设备的,这些设备具备路由能力,能够实现数据的跨网段转发。 路由是数据通信网络中最基…...

(12)-Fiddler抓包-Fiddler设置IOS手机抓包
1.简介 Fiddler不但能截获各种浏览器发出的 HTTP 请求,也可以截获各种智能手机发出的HTTP/ HTTPS 请求。 Fiddler 能捕获Android 和 Windows Phone 等设备发出的 HTTP/HTTPS 请求。同理也可以截获iOS设备发出的请求,比如 iPhone、iPad 和 MacBook 等苹…...