危险

为之则易,不为则难

0%

Whistle

🐳 Whistle is a tool for building and deploying web applications. It is a command line tool that allows you to build and deploy your web application to a server. It is written in Go and is available for Linux, macOS, and Windows.

安装和启动

1
2
3
4
# 全局安装
npm i whistle -g
# 启动
w2 start # w2 start -n username -w 123456

证书的安装

SwitchyOmega

Chrome 中安装此插件需要科学上网,若不能,可通过这儿下载。

场景:域名映射

1
2
3
# 访问 ifer.com,会解析到 127.0.0.1
127.0.0.1 ifer.com
# https://ifer.com:5500/index.html

场景:域名转发

1
2
# 访问 ifer.com 会转发到 jd.com
ifer.com jd.com

场景:模拟 HTTPS

1
2
# 模拟 HTTPS
https://ifer.com 127.0.0.1:4000

场景:Mock 数据

1
2
# Mock 数据
http://192.168.1.6:3000/dataPackage tpl://{mock.json}

场景:代码注入

1
2
# 注入 CSS
https://www.baidu.com css://C:\Users\dangp\Desktop\test\a.css
1
2
3
4
5
# 注入 JS,引入 vConsole 进行手机端调试
https://www.baidu.com jsPrepend://{vConsole.min.js} # 引入源码
https://www.baidu.com jsPrepend://{vconsole.js} # 实例化
# 手机端
# 把上面的 www.baidu.com 换成 m.baidu.com

Tips:现在 Plugins 里面已经集成了。

1
2
# whistle 中也能进行 log 输出
https://www.baidu.com log:// # 在 whistle 中也打印 log

场景:请求转到本地

1
2
www.test.cn C:\Users\dangp\Desktop\test\index.html
# https://www.test.cn C:\Users\dangp\Desktop\test\data.json

场景:调试线上代码

替换线上的 JS 文件为本地的,然后断点调试。

1
https://pss.bdstatic.com/static/superman/js/lib/jquery-1-edb203c114.10.2.js C:\Users\dangp\Desktop\test\a.js

a.js

1
2
debugger
console.log('~~~~~~')

场景:跨域处理

操作方式 1

两者一致:请求的地址和 whistle 代理的地址(当浏览器访问 https 的本地 IP 时测试未成功)。

需求:浏览器如下方式打开文件时,期望拿到请求数据。

前端代码如下(注意把下面的 IP 换成自己本机的):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/axios@1.6.8/dist/axios.min.js"></script>
</head>

<body>
Hello
<script>
axios.get("http://192.168.1.6:3000/api/users").then((response) => {
console.log(response.data);
});
</script>
</body>
</html>

后端代码如下:

1
2
3
4
5
6
7
8
9
10
11
const express = require("express");
const app = express();

app.get("/api/users", (req, res) => {
res.send({
msg: "ok",
users: [{ name: "John" }, { name: "Jane" }],
});
});

app.listen(3000, () => console.log("Server is running 3000..."));

whistle 配置如下:

1
2
# http://192.168.1.6:3000/api/users resCors://*
http://192.168.1.6:3000/api resCors://*

需要携带 Cookie 可以如下配置:

1
2
http://10.9.102.242:3000/api resCors://enable
# http://10.9.102.242:3000/api resCors://use-credentials

或者文件请求携带 Cookie 配置如下:

1
<script crossorigin="use-credentials" src="https://cdn.jsdelivr.net/npm/axios@1.6.8/dist/axios.min.js"></script>

如果配置信息较多,可以抽离到某个文件,如下:

1
http://10.9.102.242:3000/api resCors://{test-resCors.json}

test-resCors.json

1
2
3
4
5
origin: *
methods: POST
headers: x-test
credentials: true
maxAge: 300000

操作方式 2

把请求地址改成当前网站域名试试。

三者一致:浏览器的域名,请求的地址,代理的地址(用 127.0.0.1 未测试成功)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/axios@1.6.8/dist/axios.min.js"></script>
</head>
<body>
Hello
<script>
axios.get("/api/users").then((response) => {
console.log(response.data);
});
</script>
</body>
</html>

whistle 配置如下:

1
https://10.226.38.90:5500/api http://10.226.38.90:3000/api

模仿百度

http://127.0.0.1:5500/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
我是假的百度
<script>
fetch("https://www.baidu.com")
.then((res) => {
return res.text();
})
.then((res) => {
console.log(res);
document.documentElement.innerHTML = res;
});
</script>
</body>
</html>

switchyOmega

1
<-loopback>

whistle

1
2
3
www.baidu.com resCors://*
http://127.0.0.1:5500/s www.baidu.com/s
http://127.0.0.1:5500/sugrec www.baidu.com/sugrec

截图操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button id="oBtn">截图</button>
<br />
<img
border="0"
src="https://www.runoob.com/images/logo.png"
alt="runoob.com"
/>
<script src="https://cdn.bootcdn.net/ajax/libs/html2canvas/1.4.1/html2canvas.js"></script>
<script>
oBtn.addEventListener("click", function () {
html2canvas(document.body, {
// Whether to attempt to load images from a server using CORS
useCORS: true,
}).then(function (canvas) {
const a = document.createElement("a");
a.href = canvas.toDataURL();
a.download = "download.png";
a.click();
});
});
</script>
</body>
</html>
1
2
# www.runoob.com resCors://*
* resCors://*