-
Notifications
You must be signed in to change notification settings - Fork 277
FAQ
Caution
All docs are migrated to the official site https://pagespy.org from 2024.7.10.
PageSpy has prepared introductory videos for everyone. The videos cover the background of using PageSpy, how to use it, various deployment scenarios, and more. Please visit Youtube to watch and learn.
- The compatibility target for the SDK is
["chrome > 75","safari > 12", "> 0.1%", "not dead","not op_mini all"]
; - The Debugger is intended for developers and remains open when utilizing browser's new feature APIs in the source code. Therefore, we recommend using the latest version of the browser. Our target is set to
["last 2 chrome version", "last 2 firefox version", "last 2 safari version"]
.
window $pageSpy = new PageSpy({
// ... other config
autoRender: false
})
What parameters can be passed during the instantiation of PageSpy, and what are their respective purposes?
Tip
PageSpy instantiation can include the following optional parameters, each serving a specific purpose with its default values explained.
window.$pageSpy = new PageSpy({
// The SDK automatically analyzes the path from which it is imported
// to determine the server address (api) and client's origin (clientOrigin).
// If you load SDK by <script src="https://example.com/page-spy/index.min.js">, the SDK will internally set:
// - api: "example.com"
// - clientOrigin: "https://example.com"
// Manually specify if your service is deployed elsewhere.
api: "",
clientOrigin: "", // only for browser sdk
// Project serves as an aggregation of information and can be searched in the debug client's room list.
project: "default",
// Title allows users to provide custom parameters, useful for distinguishing the current debugging client.
// The corresponding information is displayed below the "Device ID" on each debug connection panel.
title: "--",
// Indicates whether the SDK, upon initialization, automatically renders the "circular white logo on a white background" control
// in the bottom left corner of the client. If set to false, you can manually render it using window.$pageSpy.render().
autoRender: true, // only for browser sdk
// Manually specify the scheme of the PageSpy service.
// Useful when the SDK cannot correctly analyze the scheme; for example, when using PageSpy's browser extension,
// it may be imported as chrome-extension://xxx/sdk/index.min.js, which the SDK might interpret as invalid "chrome-extension://"
// and fallback to ["http://", "ws://"].
// - (Default) Pass undefined or null: SDK will automatically analyze;
// - Pass a boolean value:
// - true: SDK will access PageSpy service through ["https://", "wss://"]
// - false: SDK will access PageSpy service through ["http://", "ws://"]
enableSSL: null,
// After adding support for offline replay in [email protected], the client-integrated SDK can work without
// establishing a connection with the debugger.
// Default value is false, when users set it to other values will enters "offline mode", where PageSpy
// will not create rooms or establish WebSocket connections.
offline: boolean, // only for browser sdk
// Customize the logo source
logo: '', // only for browser sdk
// Customize the logo style
logoStyle: {}, // only for browser sdk
})
PageSpy has published integration guides for all popular frameworks on the CodeSandbox platform. You can experience it online by visiting:
- React:https://codesandbox.io/p/sandbox/page-spy-with-react-k3pzzt
- Vue:https://codesandbox.io/p/sandbox/page-spy-with-vue-ft35qs
- Svelte:https://codesandbox.io/p/sandbox/page-spy-with-svelte-p6mxd6
- Angular:https://codesandbox.io/p/sandbox/page-spy-with-angular-6wg3ps
- Nextjs:https://codesandbox.io/p/sandbox/page-spy-with-nextjs-5htxv5
- Nuxtjs:https://codesandbox.io/p/sandbox/page-spy-with-nuxtjs-8znq22
https://test.jikejishu.com/ is a temporary service we set up to allow users to experience and learn PageSpy online. We do not guarantee 24-hour availability, data security, and any losses incurred are at your own risk. We strongly recommend deploying PageSpy in private servers or intranets after the initial experience.
Check if the firewall on the server or the security group rules have opened port 6752.
Here is the Nginx configuration for https://test.jikejishu.com/ as a reference:
server {
listen 443 ssl;
server_name test.jikejishu.com;
if ($scheme != https) {
rewrite ^(.*)$ https://$host$1 permanent;
}
ssl_certificate /etc/letsencrypt/live/test.jikejishu.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/test.jikejishu.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:6752;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
server {
if ($host = test.jikejishu.com) {
return 301 https://$host$request_uri;
}
listen 80;
listen [::]:80;
server_name test.jikejishu.com;
return 404;
}
How can the debugging side add some security authentication protection, allowing access only for authenticated developers?
You can implement security protection on the server by setting up an IP whitelist or using HTTP Authorization.
-
Example Nginx configuration for IP whitelist:
server { location / { # Allow only specified IP addresses to access allow <ip>; # Deny all other clients except those in the allow list deny all; } }
-
Nginx configuration for HTTP Authorization, requiring a username and password for access:
- Generate a username and password file using htpasswd:
# Enter the password when prompted and confirm it htpasswd -c /etc/nginx/.htpasswd <username>
- Configure the
auth_basic
module in the Nginx file:
server { location / { auth_basic "Please enter your username and password to access the PageSpy service"; auth_basic_user_file /etc/nginx/.htpasswd; } }
I don't want to manually integrate into my project. Is there a way to avoid modifying the business project code?
PageSpy has prepared a browser extension for you. The extension offers the following features:
- Automatically injects the latest version of the SDK.
- Automatically completes the instantiation process.
- Provides configuration rules for injected domains.
Click here to use: HuolalaTech/page-spy-extension
You can use the following script as a reference:
// ==UserScript==
// @name Inject PageSpy Script
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Inject script on xxx.yyy
// @author You
// @match <matching rules, e.g., example.com>
// @grant none
// ==/UserScript==
(function() {
'use strict';
var script1 = document.createElement('script');
script1.setAttribute('crossorigin', 'anonymous');
// Replace the actual SDK URL in a real project
script1.src = 'https://test.jikejishu.com/page-spy/index.min.js';
var script2 = document.createElement('script');
script2.textContent = 'window.$pageSpy = new PageSpy();';
document.head.prepend(script1);
script1.onload = () => {
document.head.appendChild(script2);
}
})();
The business project is deployed on HTTPS, and PageSpy is deployed on HTTP. What should I do if there are console errors?
Browsers prevent loading HTTP resources from an HTTPS site because HTTPS provides encryption and security during data transmission, while HTTP is plaintext and poses a security risk.
It is recommended to upgrade PageSpy to use HTTPS directly to resolve this issue effectively.
The simplest solution is to have the user use the PageSpy browser extension, which is suitable for highly cooperative users and PC projects. However, this premise is quite demanding.
For an H5 project in production that needs to use PageSpy, what should be done? Enabling it for all users is obviously not practical.
Consider the two-step process of PageSpy's effectiveness:
- Introducing the SDK through the
<script>
tag in thehead
; - Instantiation;
Before the second step of instantiation, the introduced <script>
does not have any effect on the project. To debug a specific user, the key lies in the second step: where to instantiate PageSpy on the user's terminal. There are two possible solutions:
-
Dynamically respond to HTML: If user identification can be obtained when requesting HTML and HTML can be dynamically injected, it's possible to decide whether to inject the <script> and instantiation logic before returning HTML to the user;
-
Let users enable it with a gesture (in planning): By default, inject the SDK but don't instantiate it. Allow users to trigger special gestures to enable debugging;
Friendly reminder: In addition to technical implementation, attention should be paid to legal and security risks.
No, direct interaction is not allowed. If you need to perform certain interactions, you can try entering code at the bottom of the Console panel for execution, and then back to the Page panel to see the interface feedback.
The Page panel renders document.documentElement.outerHTML
from the client into an iframe
element. You can inspect elements directly through the local Devtool.
Due to the differences in rendering environments between the client and the debugging side (e.g., the client's browser version being Chrome 75 and the debugging side's browser version being Chrome 120), the styles are provided for reference only.
The SDK can capture a "screenshot" of the page and send it to the debugging side. However, this approach has its limitations:
- "Images" have a larger data volume compared to text, leading to increased network transmission overhead;
- It adds to the size and complexity of the SDK;
- If there is a "style error", QA can provide precise feedback to developers on remote collaboration;
For these reasons, the styles in the Page panel are provided for reference only.
We have added support for allowing users to deploy the service for accessing by sub-path in 1.5.4 version. The installation process remains unchanged; the only adjustment required is in the nginx configuration:
server {
# ...
location /<sub-path>/ {
# the <sub-path> is same as above
rewrite ^/<sub-path>/(.*)$ /$1 break;
proxy_pass http://127.0.0.1:6752;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# the <sub-path> is same as above
location /<sub-path> {
return 301 $scheme://$host$request_uri/;
}
}
After adjusting the configuration, simply restart Nginx to enable access via subpaths. And it's important to note that you need to pass api
to tell SDK the sub-path, for example:
window.$pageSpy = new Page({
api: '<host>/<sub-path>'
})
When you deploy the service through the NPM package deployment method and execute page-spy-api
in the terminal, a configuration file named config.json
will be generated in the runtime directory. This file allows you to configure the service port and support multiple-instance deployment.
-
Modify the config.json:
{ "port": "6752", "maxLogFileSizeOfMB": "10240", "maxLogLifeTimeOfHour": "720", "corsConfig": { "allowOrigins": string[], "allowHeaders": string[], "allowMethods": string[], "exposeHeaders": string[] } }
-
Multi-instance deployment (Requires upgrading to version 1.5.0 or above)
The
rpcAddress
configuration is used for multi-instance deployment, whereip
andport
represent the IP addresses and RPC ports of multiple machines. Multiple instances communicate with each other through RPC, and the program starts the RPC service based on the machine's IP. Therefore, it is important to ensure that IP addresses are unique to avoid potential issues of message confusion or loss.{ "port": "6752", "rpcAddress": [ { "ip": "192.168.123.1", "port": "20008" }, { "ip": "192.168.123.2", "port": "20008" } ] }
Packages installed globally with pnpm
are wrapped in a shell script by pnpm
. In other words, when executing pm2 start page-spy-api
, it actually finds a shell script. pm2
is unable to interpret and execute this shell script, resulting in an error.
To resolve this issue, you can install the package using yarn
or npm
, there have a discussion: https://github.com/Unitech/pm2/issues/5416
- If you deploy using
docker
:
# Update the image
docker pull ghcr.io/huolalatech/page-spy-web:latest
# Stop the running PageSpy container
docker stop pageSpy && docker rm -f pageSpy
# Restart the container
docker run -d --restart=always -p 6752:6752 --name="pageSpy" ghcr.io/huolalatech/page-spy-web:latest
- If you deploy using NPM package:
# Update the package (yarn)
yarn global upgrade @huolala-tech/page-spy-api@latest
# Update the package (npm)
npm install -g @huolala-tech/page-spy-api@latest
# Restart using pm2
pm2 restart page-spy-api
View configuration: https://github.com/HuolalaTech/page-spy-api/blob/master/room/local_room.go#L297-L323
- If no SDK or debugging client enters the room after creation, it will be destroyed after 1 minute (in practical usage, this scenario does not exist);
- If both the SDK and debugging client are disconnected, it will be destroyed after 1 minute;
- If there is no data message interaction for 5 minutes, it will be destroyed;
- If the connection lasts for more than 1 hour, it will be automatically destroyed;
Why in alipay miniprogram, I cannot access the global variables like 'my', 'getCurrentPages' when executing remote code?
Due to historical reasons, the alipay miniprogram has forbidden the access to global variables. You can change this setting in 2 ways:
- IDE: Detail -> Compile Options -> GlobalObject (global/globalThis) Access Strategy: Accessible (Recommended)
- Config file: https://opendocs.alipay.com/mini/03dbc3?pathHash=e876dc50#globalObjectMode
- Uploaded file logs are by default kept for a maximum of the latest 10GB and for 30 days, which can be customized by modifying the configuration.
- Uploaded logs are stored in the 'log' directory within the running directory. When Docker is running, if the Docker is destroyed, the logs will also be lost. To persist logs, directory mapping -v ./log:/app/log -v ./data:/app/data can be used.