ace8
September 23, 2022, 9:05am
1
Hi Team,
I was wondering if it was possible to run 1 Cloudflare worker to redirect multiple URL. Example a site has migrated to a new website plaform which is https://example.com.au/pages/about-us and new site is https://example.com.au/about-us and we want to remove /pages is just one example but there is many others need to do example redirect /help to another platform https://example2.net/help etc
any way can create a CF worker to handle multiple redirects in a single worker? Any one have any good examples to use?
I am aware of redirect in bulk tool and would be great however free plan is limited to 20 and I need 45 redirects.
the
September 23, 2022, 11:12am
2
Hi @ace8
Sure, it is possible to use a worker as a redirector.
If you want to rewrite specific /pages/<some-page>
to /<some-page>
, you could add a condition such as
const url = new URL(request.url)
if (url.pathname.startsWith('/pages/')) {
url.pathname = url.pathname.replace('/pages/', '/')
}
else if (something === somethingElse) {
// do something else
}
// and so on
return new Response(`Redirecting to: ${url.href}`, {
status: 301,
headers: {
Location: url.href
}
})
ace8
September 23, 2022, 12:11pm
3
Hi @the thanks for that. I was reading this: Bulk redirects · Cloudflare Workers docs
and was wondering could i modify this
const externalHostname = "examples.cloudflareworkers.com"
const redirectMap = new Map([
["/bulk1", "https://" + externalHostname + "/redirect2"],
["/bulk2", "https://" + externalHostname + "/redirect3"],
["/bulk3", "https://" + externalHostname + "/redirect4"],
["/bulk4", "https://google.com"],
])
async function handleRequest(request) {
const requestURL = new URL(request.url)
const path = requestURL.pathname.split("/redirect")[1]
const location = redirectMap.get(path)
if (location) {
return Response.redirect(location, 301)
}
// If request not in map, return the original request
return fetch(request)
}
addEventListener("fetch", async event => {
event.respondWith(handleRequest(event.request))
})
But instead mdify the top part of the code to look like this instead wondering if this will work
// const externalHostname = "examples.cloudflareworkers.com" - remark this out
const redirectMap = new Map([
["/bulk1", "https://example.com.au/redirect2"],
["/bulk2", "https://example.com.au/redirect3"],
["/bulk3", "https://example.com.au/redirect4"],
["/bulk4", "https://google.com"],
])
async function handleRequest(request) {
const requestURL = new URL(request.url)
const path = requestURL.pathname.split("/redirect")[1]
const location = redirectMap.get(path)
if (location) {
return Response.redirect(location, 301)
}
// If request not in map, return the original request
return fetch(request)
}
addEventListener("fetch", async event => {
event.respondWith(handleRequest(event.request))
})
Do you know if that could work ? And would allow a bu
the
September 23, 2022, 10:10pm
4
Modifying that script would work.
You could manually add the redirects like
[ "/pages/about-us", "https://example.com.au/about-us" ],
[ "/pages/another-page", "https://example.com.au/new-location" ]
and if there is a match redirect otherwise fetch the original request. This wouldn’t need the splitting of the pathname meaning
const location = redirectMap.get(path)
// would change to
const location = redirectMap.get(requestURL.pathname)
Or if there are many pages, implement the checking of the pathname I earlier suggested, or combination of both.
ace8
September 28, 2022, 3:26am
5
the:
[ "/pages/about-us", "https://example.com.au/about-us" ],
[ "/pages/another-page", "https://example.com.au/new-location" ]
So you are suggesting this would work:
const redirectMap = new Map([
["/bulk1", "https://example.com.au/redirect2"],
["/bulk2", "https://example.com.au/redirect3"],
["/bulk3", "https://example.com.au/redirect4"],
["/bulk4", "https://google.com"],
])
async function handleRequest(request) {
const requestURL = new URL(request.url)
const path = requestURL.pathname.split("/redirect")[1]
const location = redirectMap.get(requestURL.pathname)
if (location) {
return Response.redirect(location, 301)
}
// If request not in map, return the original request
return fetch(request)
}
addEventListener("fetch", async event => {
event.respondWith(handleRequest(event.request))
})
Correct?
the
September 28, 2022, 3:54am
6
If you only want to redirect a URL with a pathname
beginning with /pages/
you would first check if the request URL contains /pages/
something like
const { pathname } = new URL(request.url)
if (pathname.startsWith('/pages/') { /* more here */ }
Then inside the if
remove /pages/
from the pathname
and check the existence of a redirect in the map something like
const location = redirectMap.get(pathname.slice(7))
if (location)
return Response.redirect(location, 301)
Otherwise the request passes through to fetch
.
ace8
September 28, 2022, 4:43am
7
@the your a weapon love your work man! Thanks.
Quick question its all working perfectly! One last thing however though is any urls not mentioned in the script basically fall back to the original request as per here:
// If request not in map, return the original request
return fetch(request)
My question is how could i replace that if none of the redirects match it will redirect everything else to https://xxxx.com for example?
the
September 28, 2022, 4:56am
8
Simply change the return fetch(request)
to return Response.redirect('https://example.com', 301)
.
If you want more fine grained control over headers, instead of Response.redirect
use
return new Response(null, {
status: 301, // or 301, 307, 308
headers: {
Location: 'https://example.com',
// other custom headers as required.
}
})
If you wish check out this script
/**
* URL Redirector — Cloudflare Workers version
* ============================================
* Shortest possible (that I have found) Cloudflare Workers URL redirector
*
* Copyright 2022 Jasiq Li and Siqli (https://siq.li)
* 2022 Coel May https://coelmay.net
*
* SPDX-License-Identifier: Jam
*/
export default {
fetch(request) {
return ((to, method) =>
(method !== "GET" && method !== "HEAD")
? new Response("Method Not Allowed", {
status: 405,
headers: {
Allow: "GET, HEAD"
}
})
This file has been truncated. show original
ace8
September 28, 2022, 5:01am
9
@the you nailed what a legend! thanks mate!
system
Closed
October 1, 2022, 5:02am
10
This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.