您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
The ultimate URL purifier
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/492078/1357329/pURLfy.js
English | 简体中文
The ultimate URL purifier.
[!NOTE] Do you know that the name "pURLfy" is a combination of "purify" and "URL"? It can be pronounced as
pjuɑrelfaɪ
.
Purify URL: Remove redundant tracking parameters, skip redirecting pages, and extract the link that really matters.
/
in the URL path.)2.1kb
.redirect
rules), it will continue to be purified.// Somewhat import `Purlfy` class from https://cdn.jsdelivr.net/gh/PRO-2684/pURLfy@latest/purlfy.min.js
const purifier = new Purlfy({ // Instantiate a Purlfy object
redirectEnabled: true,
lambdaEnabled: true,
});
const rules = await (await fetch("https://cdn.jsdelivr.net/gh/PRO-2684/pURLfy@latest/rules/<country>.json")).json(); // Rules
purifier.importRules(rules); // Import rules
const additionalRules = {}; // You can also add your own rules
purifier.importRules(additionalRules);
purifier.addEventListener("statisticschange", e => { // Add an event listener for statistics change
console.log("Statistics changed to:", e.detail);
});
purifier.purify("https://example.com/?utm_source=123").then(console.log); // Purify a URL
new Purlfy({
redirectEnabled: Boolean, // Enable the redirect mode (default: false)
lambdaEnabled: Boolean, // Enable the lambda mode (default: false)
maxIterations: Number, // Maximum number of iterations (default: 5)
statistics: { // Initial statistics
url: Number, // Number of links purified
param: Number, // Number of parameters removed
decoded: Number, // Number of URLs decoded (`param` mode)
redirected: Number, // Number of URLs redirected (`redirect` mode)
char: Number, // Number of characters deleted
},
log: Function, // Log function (default: `console.log.bind(console, "\x1b[38;2;220;20;60m[pURLfy]\x1b[0m")`)
})
importRules(rules: object): void
: Import rules.purify(url: string): Promise<object>
: Purify a URL.
url
: The URL to be purified.Promise
that resolves to an object containing:
url: string
: The purified URL.rule: string
: The matched rule.clearStatistics(): void
: Clear statistics.clearRules(): void
: Clear all imported rules.getStatistics(): object
: Get statistics.addEventListener("statisticschange", callback: function): void
: Add an event listener for statistics change.
callback
function will receive an Event
object with the detail
property containing the new statistics. (detail
might not work on nodejs - call getStatistics
)removeEventListener("statisticschange", callback: function): void
: Remove an event listener for statistics change.You can change these properties after instantiation, and they will take effect for the next call to purify
.
redirectEnabled: Boolean
: Whether the redirect mode is enabled.lambdaEnabled: Boolean
: Whether the lambda mode is enabled.maxIterations: Number
: Maximum number of iterations.The format of the rules rules
is as follows:
{
"<domain>": {
"<path>": {
// A single rule
"description": "<规则描述>",
"mode": "<模式>",
// Other parameters
"author": "<作者>"
},
// ...
},
// ...
}
<domain>
, <path>
: The domain and a part of path, such as example.com/
, path/
and page
(Note that the leading /
is removed). Here's an explanation of them:
/
, its value will be treated as a rule./
, there's more paths under it, like "folders" (theoretically, you can nest infinitely)/
is not allowed in the middle of <domain>
or <path>
.""
, it will be treated as a FallBack rule: this rule will be used when no other rules are matched at this level.<path>
, but remember to remove the /
after the domain.A simple example with comments showing the URLs that can be matched:
{
"example.com/": {
"a": {
// The rule here will match "example.com/a"
},
"path/": {
"to/": {
"page": {
// The rule here will match "example.com/path/to/page"
},
"": {
// The rule here will match "example.com/path/to", excluding "page" under it
}
},
"": {
// The rule here will match "example.com/path", excluding "to" under it
}
},
"": {
// The rule here will match "example.com", excluding "path" under it
}
},
"example.org": {
// The rule here will match every path under "example.org"
},
"": {
// Fallback: this rule will be used for all paths that are not matched
}
}
Here's an erroneous example:
{
"example.com/": {
"path/": { // Path ending with `/` will be treated as a "directory", thus you should remove the trailing `/`
// Attempting to match "example.com/path"
}
},
"example.org": { // Path not ending with `/` will be treated as a rule, thus you should add a trailing `/`
"page": {
// Attempting to match "example.org/page"
}
},
"example.net/": {
"path/to/page": { // Can't contain `/` in the middle - you should nest them
// Attempting to match "example.net/path/to/page"
}
}
}
Paths not ending with /
will be treated as a single rule, and there's multiple modes for a rule. The common parameters are as follows:
{
"description": "<Rule Description>",
"mode": "<Mode>",
// Mode-specific parameters
"author": "<Author>"
}
This table shows supported parameters for each mode:
Param\Mode | white |
black |
param |
regex |
redirect |
lambda |
---|---|---|---|---|---|---|
params |
✅ | ✅ | ✅ | ❓ | ❌ | ❌ |
decode |
❌ | ❌ | ✅ | ❓ | ❌ | ❌ |
lambda |
❌ | ❌ | ❌ | ❓ | ❌ | ✅ |
continue |
❌ | ❌ | ✅ | ❓ | ✅ | ✅ |
white
Param | Type | Default |
---|---|---|
params |
string[] |
Required |
Under Whitelist mode, only the parameters specified in params
will be kept, and others will be removed. Usually this is the most commonly used mode.
black
Param | Type | Default |
---|---|---|
params |
string[] |
Required |
Under Blacklist mode, the parameters specified in params
will be removed, and others will be kept.
param
Param | Type | Default |
---|---|---|
params |
string[] |
Required |
decode |
string[] |
["url"] |
continue |
Boolean |
true |
Under Specific Parameter mode, pURLfy will:
params
in order, until the first existing parameter is matched.decode
array in order (if the decode
value is invalid, this decoding function will be skipped).continue
is not set to false
, purify the new URL again.Currently supported decode
functions are:
url
: URL decoding (decodeURIComponent
)base64
: Base64 decoding (decodeURIComponent(escape(atob(s)))
)regex
TODO
redirect
[!CAUTION] For compatibility reasons, the
redirect
mode is disabled by default. Refer to the API documentation for enabling it.
Param | Type | Default |
---|---|---|
continue |
Boolean |
true |
Under Redirect mode, pURLfy will:
HEAD
request to the matched URL.3xx
, the Location
header will be used as the new URL.continue
is not set to false
, purify the new URL again.lambda
[!CAUTION] For security reasons, the
lambda
mode is disabled by default. Refer to the API documentation for enabling it.
Param | Type | Default |
---|---|---|
lambda |
string |
Required |
continue |
Boolean |
true |
Under Lambda mode, pURLfy will try to execute the lambda function specified in lambda
and use the result as the new URL. The function body should accept a single URL
parameter url
and return a new URL
object. For example:
{
"example.com": {
"description": "示例",
"mode": "lambda",
"lambda": "url.searchParams.delete('key'); return url;",
"continue": false,
"author": "PRO-2684"
},
// ...
}
If URL https://example.com/?key=123
matches this rule, the key
parameter will be deleted. After this operation, since continue
is set to false
, the URL returned by the function will not be purified again. Of course, this is not a good example, because this can be achieved by using Blacklist mode.