用于重定向的通配符域和路径名正则表达式
Wildcard domain and pathname regex for redirection
我正在尝试让批量重定向在 cloudflare workers 中工作。这是一个包含 to
和 from
url 的对象数组,有些将是跨域的。
const redirects = [
{
"from": "https://some.domain.tld/product/*",
"to": "https://another.domain.tld/product/*"
},
]
我想尊重通配符并尝试根据 url 的路径名进行重定向。
这是我的尝试,但这只是针对固定路径名,而不是跨域。在 workers playground 编辑器中测试跨域有点困难。
async function handleRequest(request) {
const url = new URL(request.url)
const host = url.hostname;
const path = url.pathname;
const queryStrings = url.search;
const location = redirects.find(r => {
return r.from.includes(path);
});
if (location) {
return Response.redirect('https://' + host + location.to + queryStrings, 301)
}
return fetch(request)
}
addEventListener("fetch", async event => {
event.respondWith(handleRequest(event.request))
})
如何更改此代码以使其支持使用通配符的重定向?通配符很可能总是在最后,一些路径名不会有通配符,它不会总是 /product
而是重定向对象中的任何路径名。
回答后更新:
const redirects = [
{
"from": "https://red.domain.com/product-1/*",
"to": "https://blue.domain.com/product-1/*"
},
]
async function handleRequest(request) {
const url = 'https://red.domain.com/product-1/fees';
const location = redirects.reduce((loc, r) => {
let match = url.split(r.from.replace("*", "")[1]);
if (match) return r.to.replace("*", "") + match;
}, "");
if (location) {
return Response.redirect(location, 301)
}
return fetch(request)
}
addEventListener("fetch", async event => {
event.respondWith(handleRequest(event.request))
})
结果:
https://blue.domain.com/product-1/h,,ps://red.domain.com/produc,-1/fees
您可以使用 Array#split()
将整个 URL 匹配到您的重定向,同时获取通配符“之后”的部分:
console.log(
"https://some.domain.tld/product/foo/bar/baz?test=baf".split("https://some.domain.tld/product/")[1]
)
对于不匹配此重定向的 URL,结果将是 undefined
,因此:
const redirects = [
{
"from": "https://some.domain.tld/product/*",
"to": "https://another.domain.tld/product/*"
},
]
async function handleRequest(request) {
const {url} = request;
const location = redirects.reduce((loc, r) => {
let match = url.split(r.from.replace("*","")[1]; // remove wildcard * for matching
if(match) return r.to.replace("*","") + match;
},"")
if (location) {
return Response.redirect(location, 301)
}
return fetch(request)
}
addEventListener("fetch", async event => {
event.respondWith(handleRequest(event.request))
})
我正在尝试让批量重定向在 cloudflare workers 中工作。这是一个包含 to
和 from
url 的对象数组,有些将是跨域的。
const redirects = [
{
"from": "https://some.domain.tld/product/*",
"to": "https://another.domain.tld/product/*"
},
]
我想尊重通配符并尝试根据 url 的路径名进行重定向。
这是我的尝试,但这只是针对固定路径名,而不是跨域。在 workers playground 编辑器中测试跨域有点困难。
async function handleRequest(request) {
const url = new URL(request.url)
const host = url.hostname;
const path = url.pathname;
const queryStrings = url.search;
const location = redirects.find(r => {
return r.from.includes(path);
});
if (location) {
return Response.redirect('https://' + host + location.to + queryStrings, 301)
}
return fetch(request)
}
addEventListener("fetch", async event => {
event.respondWith(handleRequest(event.request))
})
如何更改此代码以使其支持使用通配符的重定向?通配符很可能总是在最后,一些路径名不会有通配符,它不会总是 /product
而是重定向对象中的任何路径名。
回答后更新:
const redirects = [
{
"from": "https://red.domain.com/product-1/*",
"to": "https://blue.domain.com/product-1/*"
},
]
async function handleRequest(request) {
const url = 'https://red.domain.com/product-1/fees';
const location = redirects.reduce((loc, r) => {
let match = url.split(r.from.replace("*", "")[1]);
if (match) return r.to.replace("*", "") + match;
}, "");
if (location) {
return Response.redirect(location, 301)
}
return fetch(request)
}
addEventListener("fetch", async event => {
event.respondWith(handleRequest(event.request))
})
结果:
https://blue.domain.com/product-1/h,,ps://red.domain.com/produc,-1/fees
您可以使用 Array#split()
将整个 URL 匹配到您的重定向,同时获取通配符“之后”的部分:
console.log(
"https://some.domain.tld/product/foo/bar/baz?test=baf".split("https://some.domain.tld/product/")[1]
)
对于不匹配此重定向的 URL,结果将是 undefined
,因此:
const redirects = [
{
"from": "https://some.domain.tld/product/*",
"to": "https://another.domain.tld/product/*"
},
]
async function handleRequest(request) {
const {url} = request;
const location = redirects.reduce((loc, r) => {
let match = url.split(r.from.replace("*","")[1]; // remove wildcard * for matching
if(match) return r.to.replace("*","") + match;
},"")
if (location) {
return Response.redirect(location, 301)
}
return fetch(request)
}
addEventListener("fetch", async event => {
event.respondWith(handleRequest(event.request))
})