浏览器上查看发布App网页

准备

  1. Mac(arm 系列)
  2. mumu 仿真器
    https://mumu.163.com/mac/
  3. Magisk
    https://github.com/HuskyDG/magisk-files/releases
  4. Root Explorer Apk
    https://rootexplorer.co/
  5. LSPosed module
    https://github.com/LSPosed/LSPosed/releases
  6. LSPosed app
    https://lsposed.en.uptodown.com/android/download
  7. WebViewDebugHook.apk
    https://github.com/feix760/WebViewDebugHook?tab=readme-ov-file
  8. Microsoft Edge PC 版
    https://www.microsoft.com/en-us/edge/download?form=MA13FJ

安装

  1. 安装 mumu
    把上述下载的安装包安装后,开启 root 和磁盘读写权限,如下图:


    设置完后,重启 mumu

  2. 安装 Root Explorer apk
    将下载好的安装包,拖到 mumu 仿真器中,即可

  3. 安装 Magisk
    a. 将下载好的安装包,拖到 mumu 仿真器中,将自动安装;然后启动 App,按照如下图操作:


    b. 删除 mumu 自带 su 文件
    启动 Root Explorer App,进入/system/app,删掉 su 文件夹;再进入/system/sbin,删掉 su 文件
    经过上述操作,magisk 启动将不会报错了

  4. 安装 LSPosed 模块
    LSPosed-v1.9.2-7024-zygisk-release.zip下载好,不用解压;打开 magisk App,如下操作:

  5. 安装 LSPosed app
    将下载好的安装包,拖到 mumu 仿真器中,即可

  6. 安装 WebViewDebugHook.apk
    将下载好的安装包,拖到 mumu 仿真器中,即可

  7. 开启 webkit 的 debug 功能
    打开 LSPosed App,按照如下操作:



    图一是确定 LSPosed 模块是否安装成功;

  8. mumu 开启 adb

  9. 安装 Microsoft Edge 桌面版
    启动‘小金 app’,打开 Edge 浏览器,输入:edge://inspect/#devices,如下图:

Mac系统安装appium获取App布局结构

安装

  1. node >= 18.0.0
  2. Xcode
  3. npm i appium
  4. appium driver install uiautomator2
  5. appium inspect
    下载链接https://github.com/appium/appium-inspector/releases

启动

  1. 启动 appium 服务
    终端,键入appium命名,启动成功输入如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [Appium] You can provide the following URLs in your client code to connect to this server:
    http://127.0.0.1:4723/ (only accessible from the same host)
    http://169.254.220.211:4723/
    http://192.168.2.1:4723/
    http://10.3.20.52:4723/
    http://169.254.175.52:4723/
    http://10.8.9.26:4723/
    [Appium] Available drivers:
    [Appium] - uiautomator2@3.7.0 (automationName 'UiAutomator2')
    [Appium] No plugins have been installed. Use the "appium plugin" command to install the one(s) you want to use.
  2. 打开 appium inspect 客户端
    进行如下配置:

说明:
A. host 和 port,从步骤一获取
B. platformName: Android 或 iOS
C. appium:platformVersion: 13,
通过adb shell getprop ro.build.version.release获得
D. appium:automationName: “UiAutomator2”
E. appium:packageName: “com.cmschina.stock”
手机上,启动通过adb shell dumpsys activity top | grep 'ACTIVIT'获得,如招商证券
F. “appium:activity”: “.MainActivity”,
通过adb shell dumpsys activity top | grep 'ACTIVIT'获得
G. “appium:deviceName”: “21091116C”
通过adb devices -l获得
上述配置,综合如下:

1
2
3
4
5
6
7
8
{
"platformName": "Android",
"appium:platformVersion": "13",
"appium:automationName": "UiAutomator2",
"appium:packageName": "com.cmschina.stock",
"appium:activity": ".MainActivity",
"appium:deviceName": "21091116C"
}

swiperjs旋转处理

通过劫持swiper中touches对象,根据方向改变里面x和y值,完整的测试示例,如下:

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Swiper demo - default</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1"
/>
<!-- Link Swiper's CSS -->
<link
rel="stylesheet"
href="https://unpkg.com/swiper@11.1.4/swiper-bundle.min.css"
/>
<!-- <link rel="stylesheet" href="style.css" /> -->
<style>
#rotateBtn {
position: absolute;
top: 0;
left: 0;
padding: 15px;
background: red;
z-index: 100;
}

.rotate-90 {
transform: rotate(90deg);
}
</style>
</head>

<body>
<!-- Swiper -->
<div id="chart">
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">Resize me 1</div>
<div class="swiper-slide">Resize me 2</div>
<div class="swiper-slide">Resize me 3</div>
<div class="swiper-slide">Resize me 4</div>
<div class="swiper-slide">Resize me 5</div>
<div class="swiper-slide">Resize me 6</div>
<div class="swiper-slide">Resize me 7</div>
<div class="swiper-slide">Resize me 8</div>
<div class="swiper-slide">Resize me 9</div>
<div class="swiper-slide">Resize me 10</div>
</div>
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
</div>
</div>
<div id="rotateBtn">Rotate 90</div>

<!-- Swiper JS -->
<script src="https://unpkg.com/swiper@11.1.4/swiper-bundle.min.js"></script>

<!-- Initialize Swiper -->
<script>
var swiper0 = new Swiper(".swiper-container", {
slidesPerView: 3,
direction: getDirection(),
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
on: {
resize: function () {
swiper0.changeDirection(getDirection());
},
},
});

function getDirection() {
var windowWidth = window.innerWidth;
var direction = window.innerWidth <= 760 ? "vertical" : "horizontal";

return direction;
}

var rotateBtn = document.getElementById("rotateBtn");
rotateBtn.addEventListener("click", function f(params) {
console.log("rotateBtn click");
var chartRef = document.getElementById("chart");
chartRef.classList.add("rotate-90");
setRotate90(true);
});

var test = {
name: "huang",
};
var __test = {};
Object.defineProperty(test, "name", {
set: function (v) {
__test.name = v;
},
get: function () {
return __test.name;
},
});
console.log("test v", test.name);
test.name = "hzz";
console.log("test v", test.name);

var rotate90Swiper = function (swiper, optIsRotate90) {
var isRotate90 = !!optIsRotate90;
swiper.___touches = {};
swiper.___touches.currentX = swiper.touches.currentX;
Object.defineProperty(swiper.touches, "currentX", {
set: function (v) {
if (!isRotate90) {
swiper.___touches.currentX = v;
} else {
swiper.___touches.currentY = v;
}
},
get: function () {
return swiper.___touches.currentX;
},
});
swiper.___touches.currentY = swiper.touches.currentY;
Object.defineProperty(swiper.touches, "currentY", {
set: function (v) {
if (!isRotate90) {
swiper.___touches.currentY = v;
} else {
swiper.___touches.currentX = v;
}

console.log(
"set currentY",
swiper.touches,
swiper.___touches,
isRotate90
);
},
get: function () {
console.log(
"get currentY",
swiper.touches,
swiper.___touches,
isRotate90
);
return swiper.___touches.currentY;
},
});
return function (b) {
isRotate90 = b;
};
};

var setRotate90 = rotate90Swiper(swiper0, false);
</script>
<!-- <script src="script.js"></script> -->
</body>
</html>

mkcert制作自签https证书

Want to skip the tutorial below and dig in for yourself? Check out the repo and follow along with the instructions on the README.

Local https is awful
If you’re a web developer, it’s very likely you’ve used local dev sites to build your applications on. Something like example.test or mycoolsite.devlocal, right? When I’m spinning up a basic content site, I really don’t pay attention to wrapping it up in https. However, when you start digging into more complex applications, especially those requiring registration and logins, https is useful and sometimes downright required depending on your frontend.

Google Chrome (and most modern browsers), have taken a large stance against unencrypted http sites. This includes dev sites and those that use development TLDs like .test and .devlocal. Usually you’ll see a small exclamation point or some kind of notice in your address bar’s left corner, but that changes when authentication comes into play. You’ll see even larger notices about submitting information on an insecure website, and may even be blocked from performing that action.

A potential solution is “Let’s create local self-signed certificates to enable https on our site”. If we go searching for tutorials on how to accomplish that, there’s literally a massive amount of options out there for every major operating system. The general consensus if you’re doing something like this from the command line, is using a tool like openssl. Then, in your Nginx or Apache config file, enabling https, listening to the :443 port, and referencing that file as your ssl certificate.

This worked, kind of. On my local dev app, whenever I’d navigate to the https:// version, I’d be presented with a huge “THIS SITE IS INSECURE” full-screen pop-up. At first, it didn’t bother me all that much. I could just click a “Continue to insecure site” button, my browser would remember my choice, and I could continue through the site. Albeit with a large red insecure https badge in the address bar, it still got the job done.

Screenshot of Chrome giving an error that says your connection is not private for example.test

Then came the issue on newer versions of MacOS, where you wouldn’t even see a “Continue to insecure site” bypass button on Chrome’s popup. In order to actually get it to appear, you have to do this awful process of saving the ssl certificate to your desktop, opening it up in Keychain Access, and manually setting the trust for it. And even then, that just made the bypass button appear again, still showing that large insecure badge on your site’s address bar.

There has to be a better way.

In walks mkcert
I honestly don’t remember where I first came across mkcert. It might have been on a Reddit post, Twitter thread, or random StackOverflow answer, but I am so glad that I did.

So, what is it? Mkcert is a command-line tool that does two things:

It generates a local certificate authority on your machine.
It creates self-signed ssl certificates against that authority.
What this means is that whenever your browser loads up a development site that uses one of its generated certs for https, it’s validating that certificate against the dummy validation service installed on your machine. Therefore faking your browser into thinking it’s legitimate.

It’s magic!✨

Getting set up
Installation of the actual utility is pretty straightforward, and the package is available on Windows, MacOS, and Linux platforms. I’ll go through a brief overview of each, but for more detailed instructions I’d recommend checking out the README on the official repo.

Let’s get started!

For MacOS using Homebrew:
brew install mkcert
brew install nss # only if you use Firefox
For Windows using Chocolatey:
choco install mkcert
For Linux using Linuxbrew:
brew install mkcert
💥 Bam! Now you have the tool installed on your system and ready to use in your terminal.

Creating and using a certificate
If this is your first time using mkcert, you’ll need to run it with the install flag. This only needs to be done once, and it creates the local certificate authority that we talked about earlier.

Just open up your terminal, and run:
mkcert -install
You should see the following appear if everything went successfully:
Created a new local CA at “/Users/andrew/Library/Application Support/mkcert” 💥
The local CA is now installed in the system trust store! ⚡️
The local CA is now installed in the Firefox trust store (requires browser restart)! 🦊
Now that we have our authority installed, we can create an actual certificate. I recommend first navigating in your terminal to your project’s directory, maybe even creating a new directory called mkcerts or something similar.

Then, it’s just a matter of running the command:
mkcert example.test
Replacing example.test with whatever local domain you’re using to display your site on.

You can also use IP addresses, or even wildcard subdomains. Chaining them together in the same call, if you’d like one certificate for multiple different domains on one site:
mkcert example.test “*.example.test” 127.0.0.1
And if everything goes well, you should have two new files in the directory you ran that command in, example.test.pem and example.test-key.pem. Let’s use them!

All we have to do is make them accessible to our Apache or Nginx config files, and use them like we would an actual certificate from Let’s Encrypt or another authority.

In Nginx, alongside a prepared ssl block, that might look like:
server {
listen 443 ssl;
server_name example.test;
root /Users/andrew/Sites/example.test/public;
ssl_certificate /Users/andrew/Sites/example.test/mkcerts/example.test.pem;
ssl_certificate_key /Users/andrew/Sites/example.test/mkcerts/example.test-key.pem;
}
And in Apache:
<VirtualHost 127.0.0.1:443>
ServerAdmin webmaster@example.test
DocumentRoot /Users/andrew/Sites/example.test/public
ServerName example.test
SSLEngine on
SSLCertificateFile /Users/andrew/Sites/example.test/mkcerts/example.test.pem
SSLCertificateKeyFile /Users/andrew/Sites/example.test/mkcerts/example.test-key.pem

All that’s left to do is restart the webserver process, and navigate to your example site with https:// in your browser of choice. You should then be presented with a wonderful green secure badge in the address bar! ✅

That’s all folks
Hopefully after going through this article and trying out mkcert yourself, you’ve been converted to the easier way of creating and using self-signed ssl certificates to enable https on your development websites.

https://dev.to/aschmelyun/using-the-magic-of-mkcert-to-enable-valid-https-on-local-dev-sites-3a3c

制作公有证书指向本地(localhost)

Testing SSL (LetsEncrypt certificate and loopback domain)

General approach

This sets up a publically-available domain that loops back to localhost IP address 127.0.0.1. For example, this address could be localhost.kch8.com if we controlled the kch8.com domain. This relies on having a public domain name whose DNS records you can control. We can then generate LetsEncrypt certificates for this domain.

Our HTTP server runs on localhost:80 (default HTTP port). This lets us visit http://localhost.kch8.com in a web browser and see the server running on localhost:80.

We then run an HTTPS proxy server on kch8:443 (default HTTPS port) that uses the LetsEncrypt certificates we generated for localhost.kch8.com. Visiting https://localhost.kch8.com hits the proxy, which returns the correct certificates meaning the browser displays the “Secure” message. The proxy then passes the request through to the HTTP server.

Issues

  • it’s very convoluted
  • private keys etc need to be distributed to any machine running the server
  • must have control of DNS records on domain
  • LetsEncrypt certificates expire so the whole process must be repeated to get new ones (steps 5-9 below)
  • …?

Steps

  1. Create the loopback A record for localhost.kch8.com:

    In your DNS provider’s control panel:

1
2
3
4
Type: A
Name: localhost.kch8.com.
Data: 127.0.0.1
TTL: 3600
  1. After a while, the following command:
1
2
3
4
$ dig a localhost.kch8.com.

;; ANSWER SECTION:
localhost.kch8.com. 3599 IN A 127.0.0.1
  1. Install LetsEncrypt’s certbot so we can generate a valid SSL cert:
1
brew install certbot
  1. Generate a SSL cert for your domain using the DNS challenge type which means you won’t need to have a server running on this domain:
1
sudo certbot certonly --config-dir . --work-dir . --logs-dir . --manual --preferred-challenges dns
  1. Enter the domain name when prompted:
1
localhost.kch8.com
  1. Ok with logging? Yes

  2. Add the DNS record and TXT value in your DNS provider’s control panel as requested by certbot. Do not press Enter until it’s been deployed.

  3. There are a few more questions then certbot will have generated files in the directory you ran the command in:

1
2
3
4
5
6
7
live
└── localhost.kch8.com
├── README
├── cert.pem
├── chain.pem
├── fullchain.pem
└── privkey.pem
  1. Use the redbox proxy to point to the generated certificates and start on port 443:
1
sudo node redbird-proxy.js live/kch8.example.com/
  1. Set the API_URL in .env to:
1
API_URL=https://locakch8lhost.example.com/api
  1. Start HTTP client on port 80 (edit .env to set PORT=80)
1
sudo npm start
  1. Visit https://localhost.kch8.com

The HTTPS server should be available without any browser warnings. HTTP version will be available on http://localhost.kch8.com.