移动端(Safari)浏览网页时对数字禁用电话功能

  • 标准的电话号码格式是:
<a href="tel:+86-123-456-7890">1234567890</a>
  • 有时候不是电话号码的数字会被浏览器自动解析为如上电话号码格式,导致样式和布局改变

  • 忽略页面中的数字识别为电话号码, 只要把这个默认行为关闭就行

<meta name="format-detection" content="telephone=no" />
  • 这个关闭不会影响真正电话号码的识别

说明:Meta 标签中的 format-detection 属性及含义
format-detection 中文的意思是 “格式检测”,它是用来检测 html 里的一些格式的

<!-- 禁止了把数字转化为拨号链接 默认为 yes -->
<meta name="format-detection" content="telephone=no" />
<!-- 禁止作为邮箱地址 默认为 yes -->
<meta name="format-detection" content="email=no" />
<!-- 禁止跳转至地图 默认为 yes -->
<meta name="format-detection" content="adress=no" />
<meta name="format-detection" content="telephone=no,email=no,adress=no" />

在网上搜索后发现有可能有以下原因:

1.你的 VPS 被人用来做爬虫爬 Google,IP 被封

2.你的 IPv4 网段有人做爬虫,网段被封

3.你的 IPv6 网段有人做爬虫,网段被封

IPv6 网段被封

强制你的 VPS 用 IPv4 来访问,具体方法在 /etc/sysctl.conf 后追加

# disable ipv6
net.ipv6.conf.all.disable_ipv6=1
net.ipv6.conf.default.disable_ipv6=1
net.ipv6.conf.lo.disable_ipv6=1

IPv4 网段被封

强制 VPS 使用 IPv6 访问,确认打开 VPS 上的 IPv6 功能,更改 VPS 的 hosts 中指定 Google Schoolar 的 IPv6 地址,编辑/etc/hosts后追加:

## Scholar
## type 'host google.com' to get the correct ipv6 address or
## visit https://github.com/lennylxx/ipv6-hosts
2404:6800:4004:81a::200e scholar.google.cn
2404:6800:4004:81a::200e scholar.google.com.hk
2404:6800:4004:81a::200e scholar.google.com
2404:6800:4004:81a::200e scholar.l.google.com

更改配置后,重启 SS

购买 VPS 服务器

vultr 注册地址:https://www.vultr.com/

利用 ipip 这个网站的 实用工具里的 ping 来全国性的 ping 我们的主机,检测连通性

部署 VPS 服务器

ssh 工具

Win:
使用软件 PuTTY
打开软件
Host Name (or IP address) 写你服务器的 IP 地址
Port 默认 22
Connection type 选择 SSH
Open

Mac:
默认有 SSH 命令
ssh root@IP
输入用户名和密码,用户名为 root
login as: root
root@IP’s password:

安装服务

CentOS/Debian/Ubuntu ShadowsocksR 单/多端口 一键管理脚本
https://doub.io/ss-jc42/

yum -y install wget

wget -N --no-check-certificate https://softs.fun/Bash/ssr.sh && chmod +x ssr.sh && bash ssr.sh

备用脚本:

yum -y install wget

wget -N --no-check-certificate https://raw.githubusercontent.com/ToyoDAdoubi/doubi/master/ssr.sh && chmod +x ssr.sh && bash ssr.sh

复制上面的代码到 VPS 服务器里,按回车键,脚本会自动安装,以后只需要运行 bash ssr.sh 这个快捷命令就可以出现下图的界面进行设置。

  1. 安装 SSR 服务端
  2. 设置端口和密码
  3. 设置的加密方式: aes-256-cfb
  4. 选择协议插件: auth_sha1_v4
  5. 选择混淆插件 plain

ShadowsocksR MudbJSON 模式多用户一键脚本 支持流量限制
https://doub.io/ss-jc60/

wget -N --no-check-certificate https://softs.fun/Bash/ssrmu.sh && chmod +x ssrmu.sh && bash ssrmu.sh

备用下载地址

wget -N --no-check-certificate https://raw.githubusercontent.com/ToyoDAdoubi/doubi/master/ssrmu.sh && chmod +x ssrmu.sh && bash ssrmu.sh
bash ssrmu.sh

测速脚本官方地址

wget https://raw.githubusercontent.com/oooldking/script/master/superbench.sh
chmod +x superbench.sh
./superbench.sh

加速

锐速/BBR/魔改 BBR/KCPTUN 加速效果对比测试

【原版 BBR】

wget --no-check-certificate https://github.com/teddysun/across/raw/master/bbr.sh
chmod +x bbr.sh
./bbr.sh

# 重启服务器

# 验证是否安装成功
sysctl net.ipv4.tcp_congestion_control
# 得到如下结果表示安装成功
net.ipv4.tcp_congestion_control = bbr

【魔改 BBR】

只有 centos 和 debain 版

# centos 版
wget --no-check-certificate https://raw.githubusercontent.com/tcp-nanqinlang/general/master/General/CentOS/bash/tcp_nanqinlang-1.3.2.sh
bash tcp_nanqinlang-1.3.2.sh

# debain 版
wget --no-check-certificate https://github.com/tcp-nanqinlang/general/releases/download/3.4.2.1/tcp_nanqinlang-fool-1.3.0.sh
bash tcp_nanqinlang-fool-1.3.0.sh

# 选择 1 安装内核,重启

# 运行 选择 2 安装并开启算法
bash tcp_nanqinlang-1.3.2.sh
# 选择 2 安装并开启算法

【BBRPlus(BBR v2.0)】

Github 项目地址:https://github.com/cx9208/bbrplus

一键脚本(仅CentOS)

yum -y install wget && wget "https://github.com/cx9208/bbrplus/raw/master/ok_bbrplus_centos.sh" && chmod +x ok_bbrplus_centos.sh && ./ok_bbrplus_centos.sh

等待安装完成,重启,重启之后,按照以下步骤检查是否成功:

执行 uname -r,显示 4.14.129-bbrplus 则切换内核成功

执行 lsmod | grep bbr,显示有 bbrplus 则开启成功

解决某些 npm 包无法下载的问题

如 electron sass

修改 ~/.npmrc,或当前项目下的.npmrc 文件(如果没有可以新建)增加如下内容

registry=https://registry.npm.taobao.org
sass_binary_site=https://npm.taobao.org/mirrors/node-sass/
phantomjs_cdnurl=http://npm.taobao.org/mirrors/phantomjs
electron_mirror=http://npm.taobao.org/mirrors/electron/
chromedriver_cdnurl=http://npm.taobao.org/mirrors/chromedriver

淘宝 npm 镜像 https://npm.taobao.org/

npm 官网
npm 文档
npm 中文文档

npm 基本命令

# 更新 npm
npm -v|--version
npm install npm@latest -g

# nvm : npm Version Manager

# 搜索包
npm search <pkg>

# 安装包
npm install [<@scope>/]<pkg> # [<@scope>/] 安装限定范围的包
npm install [<@scope>/]<pkg>@<tag>
npm install [<@scope>/]<pkg>@<version>
npm install [<@scope>/]<pkg>@<version range>
npm install <folder>
npm install <tarball file> # .tar, .tar.gz, or .tgz
npm install <tarball url>

# 公有仓库
npm install user/project # 默认 github
npm install bitbucket:user/project
npm install gitlab:user/project#semver:^5.0 # semver 版本
npm install git+https://git@github.com/user/project.git
npm install git+ssh://git@github.com/user/project.git
npm install git://github.com/user/project.git


npm install <pkg> -S|--save # 安装到 dependencies
npm install <pkg> -D|--save-dev # 安装到 devDependencies

# --verbose 参数 显示安装的详细信息
npm i --verbose

# --production 参数 只会安装 dependencies 依赖,而忽略 devDependencies 依赖,用于生产环境
npm i --production

# 安装全局包
npm install -g <pkg>

# 更新包
npm outdated # 检查可以更新的模块
npm update # 更新全部本地包
# 更新全局安装的包
npm update -g # 更新全部
npm update -g| --global <pkg> # 更新指定包

# 更新方式 1
# 手动修改 package.json 中依赖包版本,之后执行
npm install --force

# 更新方式 2 使用第三方插件:
npm install -g npm-check-updates
ncu # 查看可更新包
ncu -u # 更新 package.json
npm install # 升级到最新版本

# 删除本地包
npm uninstall <pkg>
npm uninstall --save <pkg> # 从 `package.json` 文件中删除依赖

# 卸载全局安装的包
npm uninstall -g <pkg>

# 打开官网
npm docs|home [<pkg>]
# 打开源码仓库页面
npm repo [<pkg>]

# 初始化一个项目,创建一个 package.json 文件,项目名不能为中文
npm init
# 创建默认 package.json 文件 快速的初始化一个项目,会使用文件夹名称作为项目名
npm init --yes or -y

简写

npm install  可简写成 npm i

npm uninstall 可简写成 npm uni

npm 修改源

修改全局配置

  • 进入~/.npmrc 增加 registry=https://registry.npm.taobao.org
  • 通过命令 npm config set registry https://registry.npm.taobao.org

修改当前项目的 npm 源

package.json 同级目录下创建 .npmrc 文件,增加 registry=https://registry.npm.taobao.org

临时使用指定源下载 npm install jquery --registry=https://registry.npm.taobao.org

使用 nrm 管理源

npm 配置文件

# .npmrc 配置文件位置(~/.npmrc)
npm config list

# npm 缓存目录,默认 C:\Users\<username>\AppData\Roaming\npm-cache
npm config get cache

# 删除 npm 缓存:注意:如果网速慢的话,会导致下载失败。 再重新下载之前,建议使用该命令,清除刚才下载的缓存,否则有可能一直无法下载成功
npm cache clean --force | -f

# npm 全局 node 包位置: 默认在 C:\Users\用户名\AppData\Roaming\npm目录下
npm config get prefix
# 或者
npm root -g

# 修改 npm 全局文件位置及缓存文件位置
npm config set prefix "<new_path>"
npm config set cache "<new_path>"

版本号

使用 NPM 下载和发布代码时都会接触到版本号。NPM 使用语义版本号来管理代码

语义版本号分为 X.Y.Z 三位,分别代表主版本号、次版本号和补丁版本号。当代码变更时,版本号按以下原则更新。

  • 如果只是修复 bug,需要更新 Z 位
  • 如果是新增了功能,但是向下兼容,需要更新 Y 位
  • 如果有大变动,向下不兼容,需要更新 X 位

nrm 使用

nrm:npm registry manager(npm 仓库地址管理工具)

# 查看配置列表,带 `*` 号即为当前使用的配置
nrm ls

# 切换源
nrm use 源的别名

# 添加源
nrm add 别名 地址

# 测速
nrm test 别名

# 删除源
nrm del 别名

查看项目安装了那些包

npm list --depth=0 [--dev | --production]
npm list --depth=0

–depth 表示深度,我们使用的模块会有依赖,深度为零的时候,不会显示依赖模块

查看全局安装的包

npm list --depth=0 --global

package.json 文件

package.json 文件,包(项目)描述文件,用来管理组织一个包(项目),它是一个纯 JSON 格式的

  • 作用:描述当前项目(包)的信息,描述当前包(项目)的依赖项
  • 如何生成:npm init或者npm init -y
  • 作用
    • 作为一个标准的包,必须要有package.json文件进行描述
    • 一个项目的 node_modules 目录通常都会很大,不用拷贝 node_modules 目录,可以通过 package.json 文件配合npm install 直接安装项目所有的依赖项
  • 描述内容
{
"name": "myproject", // 描述了包的名字,不能有中文
"version": "1.0.0",
"description": "", // 包的描述信息
"main": "index.js", // 入口文件
"scripts": {
// 配置一些脚本
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [], // 关键字(方便搜索)
"author": "", // 作者信息
"license": "ISC", // 许可证,开源协议
"dependencies": {
// 项目依赖
"bootstrap": "^3.3.7",
"jquery": "^3.3.1"
}
}

注意:一个合法的 package.json,必须要有 name 和 version 两个属性

http://www.asciiworld.com/
https://github.com/Blankj/awesome-comment

 -------------------------
< Just have fun with gist >
-------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
//When I wrote this, only God and I understood what I was doing
//Now, God only knows

安装 dcoker

ubuntu 16.04 (LTS) 安装 docker

参考官网安装方法 https://docs.docker.com/engine/install/ubuntu/

卸载旧版本

$ sudo apt-get remove docker docker-engine docker.io containerd runc

镜像仓库方式安装

设置镜像仓库
# 更新 apt 软件包索引:
$ sudo apt-get update
# 安装软件包,以允许 apt 通过 HTTPS 使用镜像仓库:
$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
# 添加 Docker 的官方 GPG 密钥:
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 验证密钥指纹是否为 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88。
$ sudo apt-key fingerprint 0EBFCD88

# 设置 stable 镜像仓库
# amd64:
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

使用国内源

# 更换国内软件源,推荐中国科技大学的源
$ sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
$ sudo sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
$ sudo apt update
# 安装需要的包
$ sudo apt install apt-transport-https ca-certificates software-properties-common curl
# 添加 GPG 密钥,并添加 Docker-ce 软件源,这里还是以中国科技大学的 Docker-ce 源为例
$ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu \
$(lsb_release -cs) stable"
# 添加成功后更新软件包缓存
$ sudo apt update
# 安装 Docker-ce
$ sudo apt install docker-ce
安装 DOCKER CE
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
# 安装指定版本
$ apt-cache madison docker-ce

docker-ce | 5:18.09.1~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
docker-ce | 5:18.09.0~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
docker-ce | 18.06.0~ce~3-0~ubuntu | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
docker-ce | 18.03.1~ce~3-0~ubuntu | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
...

$ sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io

启动 docker daemon
否则会报错:docker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?.
See ‘docker run –help’.

$ sudo service docker start
# sudo systemctl enable docker
# sudo systemctl start docker

验证是否正确安装

$ sudo docker run hello-world

此命令将下载一个测试镜像并在容器中运行它。容器运行时,它将输出一条参考消息并退出

升级 docker ce

如需升级 Docker CE,首先运行 sudo apt-get update,然后按照顺序执行操作,并选择您要安装的新版本

卸载 docker ce
$ sudo apt-get purge docker-ce docker-ce-cli containerd.io

主机上的镜像、容器、存储卷、或定制配置文件不会自动删除。如需删除所有镜像、容器和存储卷,请运行下列命令:

$ sudo rm -rf /var/lib/docker
将 docker 配置为在启动时启动

使用脚本安装

curl -sSL https://get.docker.com/ | sh

# 将用户添加到docker组,可以用非root用户使用docker
$ sudo usermod -aG docker <your-user>

国内的服务器可以使用如下脚本加速安装,

# 阿里云的安装脚本
curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh -
# DaoCloud 的安装脚本
curl -sSL https://get.daocloud.io/docker | sh

centos 安装 docker

参考官网安装方法 https://docs.docker.com/engine/install/centos/

卸载旧版本(如果安装过旧版本的话)

$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine

安装需要的软件包, yum-util 提供 yum-config-manager 功能,另外两个是 devicemapper 驱动依赖的

$ sudo yum install -y yum-utils

设置 yum 源

$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo

安装

$ sudo yum install docker-ce

# 可以查看所有仓库中所有 docker 版本,并选择特定版本安装
$ yum list docker-ce --showduplicates | sort -r
$ sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io

# 启动 Docker,设置开机启动,停止 Docker
$ sudo systemctl start docker
$ sudo systemctl enable docker
$ sudo systemctl stop docker

卸载

$ sudo yum remove docker-ce docker-ce-cli containerd.io
$ sudo rm -rf /var/lib/docker

常见问题

# 报错:Requires: container-selinux >= 2:2.74
You could try using --skip-broken to work around the problem

$ wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
$ yum install epel-release # 阿里云上的 epel 源
$ yum makecache
$ yum install container-selinux
# Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.

卸载 docker 重新安装

使用 docker

配置镜像加速

修改 docker 源

修改配置文件 /etc/docker/daemon.json(Linux) 或者 %programdata%\docker\config\daemon.json(Window)

如果没有新建一个

{
"registry-mirrors": ["https://registry.docker-cn.com"]
}

重启 docker

安装镜像

安装 Ubuntu 镜像

docker search ubuntu # 查找 Ubuntu 镜像
docker pull ubuntu # 安装 Ubuntu 镜像
docker images #查看 docker 镜像

# 创建并运行 docker 容器
docker run -it -d --name ubuntu_test -p 8088:80 ubuntu
# --name 自定义容器名,-p 指定端口映射,前者为虚拟机端口,后者为容器端口,成功后返回 id
# 多个 -p 指定多个端口映射

# 运行 docker 容器 启动一个 bash 交互终端
docker run -it 容器名:容器tag /bin/bash

docker start container_id


# 查看所有启动的容器(查看所有容器加 -a)
docker ps

# 根据 id 查看容器信息
docker inspect id

# 进入docker(或者把容器id改为容器名,也可以进入)
docker exec -it 容器id或容器名 /bin/bash

# OCI runtime exec failed: exec failed: container_linux.go:349: starting container process caused "exec: \"/bin/bash\": stat /bin/bash: no such file or directory": unknown
# 解决
# docker exec -it 容器id或容器名 /bin/sh
# docker exec -it 容器id或容器名 bash
# docker exec -it 容器id或容器名 sh

# 退出容器
exit

# 停止容器
docker stop id

# 删除容器
docker rm 容器id

# 删除镜像
docker rmi 删除镜像

备份镜像

# 制作 docker 镜像  1.0 为版本号
docker commit 98 my-ubuntu:1.0

# 查看镜像是否创建
docker images

# 保存镜像到 docker 账号中
# 登录进 Docker 注册中心
docker login

# 推送镜像
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
docker tag my-ubuntu:1.0 cuilongjin/my-ubuntu:1.0
docker push cuilongjin/my-ubuntu:1.0

# 打包镜像并查看
docker save -o my-ubuntu.tar my-ubuntu:1.0

恢复容器

# 从docker账号中拉取
docker pull cuilongjin/my-ubuntu:1.0

# 从本地
docker load -i ~/my-ubuntu.tar

# docker images

# 用加载的镜像去运行Docker容器
docker run -d -p 80:80 my-ubuntu

docker 给已存在的容器添加或修改端口映射

方式 1:

提交一个运行中的容器为镜像

$ docker commit containerid foo/live

运行镜像并添加端口

$ docker run -d -p 8000:80  foo/live /bin/bash

方式 2:iptable 转发端口

将容器的 8000 端口映射到 docker 主机的 8001 端口

$ iptables -t nat -A  DOCKER -p tcp --dport 5001 -j DNAT --to-destination 45.77.150.20:8000

docker 容器使用问题

Centos7 docker 容器报 docker Failed to get D-Bus connection 错误

$ systemctl start nginx
Failed to get D-Bus connection: Operation not permitted。

原因是 dbus-daemon 没能启动

解决方法

docker run -it -d --name ubuntu_test -p 8088:80 ubuntu
$ docker run --privileged -ti --name test1 centos /usr/sbin/init

ssh 链接 docker 容器

进入容器

安装依赖

yum install passwd openssl openssh-server openssh-clients -y

安装 service 命令:

yum install initscripts -y

修改密码:

passwd

修改配置:

vi /etc/ssh/sshd_config

PubkeyAuthentication yes #启用公钥私钥配对认证方式
AuthorizedKeysFile .ssh/authorized_keys #公钥文件路径

PermitRootLogin yes #root 能使用 ssh 登录

重启 ssh 服务,并设置开机启动:

service sshd restartchkconfig sshd on

如果无法执行,可试着执行:

systemctl start sshd.service systemctl enable sshd.service

service sshd restart

运行 docker exec -it 容器 /bin/bash 出现如下错误

OCI runtime exec failed: exec failed: container_linux.go:346: starting container process caused "exec: \"/bin/bash\": stat /bin/bash: no such file or directory": unknown

解决方式:尝试使用如下命令

sudo docker exec -it 容器 /bin/sh
sudo docker exec -it 容器 bash

docker-compose

如果你想要通过 docker-compose 统一管理你的 Docker container,这里也可以安装一下

官方文档:https://docs.docker.com/compose/install/

sudo curl -L https://github.com/docker/compose/releases/download/1.26.2/run.sh > /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

使用 pip 安装

pip install docker-compose

运行一下 docker-compose version 来检测一下是否成功

创建配置文件

创建一个名为 docker-compose.yml 的配置文件

version: '3'
services:
v2ray1:
image: v2fly/v2fly-core # 镜像名称
container_name: v2ray # 容器名称
restart: always
command: v2ray -config=/etc/v2ray/config.json # 覆盖容器启动后默认执行的命令
ports:
# HOST:CONTAINER
- '44222:44222' # 端口
#- "127.0.0.1:8889:8889"
volumes:
# HOST:CONTAINER
- ./config:/etc/v2ray # 目录
#- /etc/v2ray/v2ray.crt:/etc/v2ray/v2ray.crt
#- /etc/v2ray/v2ray.key:/etc/v2ray/v2ray.key

v2ray2:
build:
context: ./dir # context 选项可以是 Dockerfile 的文件路径,也可以是到链接到 git 仓库的 url
dockerfile: path/of/Dockerfile # 使用此 dockerfile 文件来构建,必须指定构建路径

命令

以下命令需要在 docker-compose.yml 所在目录下执行

docker-compose up -d # 部署 v2ray
docker-compose start v2ray # 启动 v2ray
docker-compose stop v2ray # 停止 v2ray
docker-compose restart v2ray # 重启 v2ray
docker stop v2ray && docker rm v2ray # 删除 v2ray
docker-compose pull && docker-compose up -d # 更新 v2ray

一些调试工具

  1. 直接在 chrome,firefox 等开启模拟器调试,简单直接,还能模拟网络等,但是无法 100% 还原手机的真实情况

  2. chrome 远程调试功能

    chrome://inspect/#devices

    需要连接数据线,其次是设置比较繁琐,而且还限制了 android 手机。对于 IOS 的调试则可能要使用 Safari 的另一套工具

  3. weinre:远程调试,在 PC 上生成一个像 chrome 开发工具一样的调试器,需要手动引入 js

  4. Eruda、vConsole:在移动端页面上生成一个调试器,调试信息会挡住操作元素,查看复杂数据结构的 log 不方便,需要手动引入 js

  5. 安装各种虚拟机 sdk,在电脑上进行手机调试。能比较真实模拟手机,但是安装繁琐,操作不方便,无法模拟真实的手势操作

Eruda

https://github.com/liriliri/eruda

Eruda 是一个专为手机网页前端设计的调试面板,类似 DevTools 的迷你版,其主要功能包括:捕获 console 日志、检查元素状态、捕获 XHR 请求、显示本地存储和 Cookie 信息等等。

  1. 按钮拖拽,面板透明度大小设置。
  2. Console 面板:捕获 Console 日志,支持 log、error、info、warn、dir、time/timeEnd、clear、count、assert、table;支持占位符,包括%c 自定义样式输出;支持按日志类型及正则表达式过滤;支持快捷命令加载 underscore、jQuery 库;支持 JavaScript 脚本执行。
  3. Elements 面板:查看标签内容及属性;查看应用在 Dom 上的样式;支持页面元素高亮;支持屏幕直接点击选取;查看 Dom 上绑定的各类事件。
  4. Network 面板:捕获请求,查看发送数据、返回头、返回内容等信息。
  5. Resources 面板:查看并清除 localStorage、sessionStorage 及 cookie;查看页面加载脚本及样式文件;查看页面加载图片。
  6. Sources 面板:查看页面源码;格式化 html,css,js 代码及 json 数据。
  7. Info 面板:输出 URL 及 User Agent;支持自定义输出内容。
  8. Snippets 面板:页面元素添加边框;加时间戳刷新页面;支持自定义代码片段。

使用

通过 CDN 使用:

<script src="//cdn.bootcss.com/eruda/1.5.2/eruda.min.js"></script>
<script>
eruda.init()
</script>

通过 npm 安装:

npm install eruda --save

在页面中加载脚本:

<script src="node_modules/eruda/eruda.min.js"></script>
<script>
eruda.init()
</script>

Js 文件对于移动端来说略重(gzip 后大概 100kb)。建议通过 url 参数来控制是否加载调试器,比如:

;(function() {
var src = 'node_modules/eruda/eruda.min.js'
if (!/eruda=true/.test(window.location) && localStorage.getItem('active-eruda') != 'true') return
document.write('<scr' + 'ipt src="' + src + '"></scr' + 'ipt>')
document.write('<scr' + 'ipt>eruda.init();</scr' + 'ipt>')
})()

初始化时可以传入配置:

  • container:用于插件初始化的 Dom 元素,如果不设置,默认创建 div 作为容器直接置于 html 根结点下面
  • tool:指定要初始化哪些面板,默认加载所有
let el = document.createElement('div')
document.body.appendChild(el)

eruda.init({
container: el,
tool: ['console', 'elements'],
useShadowDom: true
})

vConsole

https://github.com/Tencent/vConsole

一个轻量、可拓展、针对手机网页的前端开发者调试面板

特性

  • 查看 console 日志
  • 查看网络请求
  • 查看页面 element 结构
  • 查看 Cookies、localStorage 和 SessionStorage
  • 手动执行 JS 命令行
  • 自定义插件

使用说明

下载 vConsole 的最新版本(不要直接下载 dev 分支下的 dist/vconsole.min.js),复制 dist/vconsole.min.js 到项目中:

在 HTML 中引入 vConsole 模块

<script src="dist/vconsole.min.js"></script>
<script>
// 初始化
var vConsole = new VConsole()
console.log('Hello world')
</script>

在 vue 项目中:使用 npm 安装

npm install vconsole

在 main.js 中引入

import VConsole from 'vconsole'
const isDebug = true
// 本地开发调试注入 vConsole
if (isDebug) {
new VConsole()
}

weinre

http://people.apache.org/~pmuellr/weinre/docs/latest/Home.html

  1. Element: 查看/修改 dom,查看/修改 dom CSS
  2. Resources:查看/修改 localStorage, sessionStorage
  3. Network:查看网络请求
  4. Timeline:
  5. Console:查看控制台输出

不能做 JS 调试

使用

# 安装
npm install -g weinre

# 启动 weinre 服务
weinre --boundHost 192.168.3.44 --httpPort 8888

启动调试客户端
在浏览器中打开 'http://192.168.3.44:8888' 即可启动调试客户端

在需要调试的页面中添加如下
<script src="http://192.168.3.44:8888/target/target-script-min.js#anonymous"></script>

spy-debugger

https://github.com/wuchangming/spy-debugger

微信调试,各种 WebView 样式调试、手机浏览器的页面真机调试。便捷的远程调试手机页面、抓包工具,支持:HTTP/HTTPS,无需 USB 连接设备

spy-debugger 集成了weinre,简化了weinre需要给每个调试的页面添加 js 代码。原理是拦截所有 html 页面请求注入weinre所需要的 js 代码。让页面调试更加方便

1、页面调试+抓包
2、操作简单,无需 USB 连接设备
3、支持 HTTPS
4、spy-debugger内部集成了weinrenode-mitmproxyAnyProxy
5、自动忽略原生 App 发起的 https 请求,只拦截 webview 发起的 https 请求。对使用了 SSL pinning 技术的原生 App 不造成任何影响。
6、可以配合其它代理工具一起使用(默认使用 AnyProxy) (设置外部代理)

基本使用

# 安装
npm install spy-debugger -g
# 启动
spy-debugger
#设置手机的HTTP代理
代理IP地址设置为PC的IP地址,端口为spy-debugger的启动端口(默认端口:9888)
# 手机安装证书
手机浏览器访问 http://s.xxx
设置->通用->描述文件与设备管理->找到node-mitmproxy CA(安装)
设置->通用->关于本机->证书信任设置-> 找到node-mitmproxy CA(打开)

自定义选项

# 自定义端口
spy-debugger -p 8888

# 设置页面内容为可编辑模式
spy-debugger -w true

# 是否只拦截浏览器发起的https请求(默认: true)
spy-debugger -b false

# 是否允许weinre监控iframe加载的页面(默认: false)
spy-debugger -i true

# 是否允许 HTTP 缓存(默认: false)
spy-debugger -c true

m-console

https://github.com/fwon/m-console

手机远程调试工具,手机通过代理连接上 PC 后,可以在 PC 版浏览器打印 log 和错误日志

需要手动给每个调试的页面添加 js 代码

DebugGap-VIDE

https://www.debuggap.com/debug_webview.html

Mobile Debug

https://www.mobiledebug.com/

whistle

https://segmentfault.com/a/1190000016058875?utm_source=tag-newest
http://wproxy.org/whistle/

chii

https://github.com/liriliri/chii

抓包工具

AnyProxy
https://github.com/alibaba/anyproxy
Zan Proxy
https://youzan.github.io/zan-proxy/

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise

promise 的三个状态

  • pending : 等待 (等待成功或者失败去调用)
  • fulfilled : 成功调用(resolve)
  • rejected : 失败调用(reject)

有 throw 也相当于 reject

let p1 = new Promise(() => {}) // Promise {<pending>}
let p2 = new Promise((resolve, reject) => { resolve('成功') }) // Promise {<fulfilled>: '成功'}
let p3 = new Promise((resolve, reject) => { reject('失败') }) // Promise {<rejected>: '失败'}
let p4 = new Promise((resolve, reject) => { throw('报错') }) //Promise {<rejected>: '报错'}

Promise 静态方法

Promise.resolve()
Promise.reject()
Promise.all()
Promise.race()
Promise.any()

Promise.resolve()

Promise.resolve方法的参数分成四种情况

  1. 参数是一个 Promise 实例: 不做任何修改、原封不动地返回这个实例
let p = new Promise((resolve, reject) => { resolve('成功') })
Promise.resolve(p) === p // true
  1. 参数是一个thenable对象(thenable对象指的是具有then方法的对象): 会将这个对象转为 Promise 对象,然后立即执行thenable对象的then方法,执行结果作为后续方法的参数
let thenable = {
then: function(resolve, reject) { resolve('张三') }
}
let p = Promise.resolve(thenable)
p.then((res) => {
console.log(res) // '张三'
})
  1. 参数不是具有then方法的对象,或根本就不是对象: 返回一个新的状态为resolved的 Promise 对象,参数会作为后续方法的参数
const p = Promise.resolve('张三')
p.then((res) => {
console.log(res) // '张三'
})
  1. 不带有任何参数:返回一个新的状态为resolved的 Promise 对象
const p = Promise.resolve()
p.then((res) => {
console.log(res) // undefined
})

Promise.reject()

Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected

Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数。这一点与Promise.resolve方法不一致

const thenable = {
then(resolve, reject) {
reject('出错了')
}
}
Promise.reject(thenable)
.catch(e => {
console.log(e === thenable) // true
})

上面代码中,Promise.reject 方法的参数是一个thenable对象,执行以后,后面catch方法的参数不是reject抛出的“出错了”这个字符串,而是thenable对象。

all 和 race

Promise.all():resolve回调执行是在所有输入的promise的resolve回调都结束,或者输入的iterable里没有promise了的时候。reject回调执行是,只要任何一个输入的promise的reject回调执行或者输入不合法的promise就会立即抛出错误,并且reject的是第一个抛出的错误信息

Promise.race():始终返回最快的那一个promise,不管resolve还是reject

Promise.prototype 成员

  • then() :用于获取异步操作成功时的结果 -> resolve
  • catch():用于获取异步操作失败时的结果 -> reject
  • finally():不管 Promise 最后状态如何,都会执行的操作,finally 方法的回调函数不接受任何参数
promise.then(successCallback, failureCallback)
promise.catch(failureCallback)

then 第一个参数是resolved状态的回调函数,如果第一个参数不是函数,则会在内部被替换为 (x) => x,即原样返回 promise 最终结果的函数
then 第二个参数(可选)是rejected状态的回调函数
catch(failureCallback) 是 then(null, failureCallback) 的缩略形式
then方法返回的是一个新的Promise实例

async 和 await

  • async / await 用同步编写代码的方式 处理异步操作的一个方案
  • async:修饰 (修饰一个内部有异步操作的函数) 格式 : async + 函数 (里面有异步操作的函数)
  • await : 等待 (等上一个异步操作完成啊 , 修饰 一个结果是 promise 的)异步操作 格式 : await + 异步操作(结果 promise 对象)
  • async 和 await 是成对出现的,await 只能在 async 函数中使用

https://juejin.cn/post/6945319439772434469#heading-4