cover

Customize Your Jike Yellow Page Domain

sorcererxw

Analysis

Generally, using Cloudflare Worker for edge computing is very suitable for reverse proxy. We can try to use Cloudflare Worker to mount a custom domain for Jike Yellow Page (hereinafter referred to as YP).

First, let's analyze the web page rendering process of YP:

  • Load the webpage GET jike.city/xxxxx
  • Load JS file according to HTML GET static.codefuture.top/_next/xxxxx.js
  • Run JS to call the interface, extract the path from the current router, and call the interface to get data GET api.ruoguoapp.com/xxxx
  • Render web page

Whether it's CDN or api interface, cross-domain checks (anti-hotlinking) will be performed, so all network requests must occur through the worker itself as a proxy.

After understanding this process, we can formulate a simple hijacking scheme:

  • Use worker to fetch the original webpage.

    If the current webpage path is not the configured username, issue a 302 to instruct the browser to redirect to the specific path, which facilitates subsequent js to extract parameters through the path.

  • Replace all uses of static.codefuture.top in the webpage, hijacking all static file links to proxy yourself.
  • When proxying the js file, replace api.ruguoapp.com in the js file with your own, hijacking all api requests.

Practice

Configure Domain and Worker

Create a new subdomain proxied by Cloudflare
Create a worker

Writing the script

You can directly write scripts for the worker using Quick Edit.
addEventListener('fetch', event => {
    event.respondWith(fetchAndApply(event.request).catch(err=>console.error(err)));
})

// 替换为自己的 username
const username = "sorcererxw"

async function fetchAndApply(request) {
  let url = new URL(request.url)
  const sourceHost = url.host
  
  // handle static
  if(/^\/static/.test(url.pathname)) {
    url.protocol = 'https:'
    url.host = "static.codefuture.top"
    url.pathname = url.pathname.replace(/\/static/,"")
    const rsp = await fetch(url.href)
    if(/\.js$/.test(url.pathname)) {
      let text = await rsp.text()
      text = text.replaceAll("api.ruguoapp.com", sourceHost+"/api")
      text = text.replaceAll("static.codefuture.top", "/static")
      const header = new Headers(rsp.headers)
      return new Response(text, {
        status: rsp.status,
        headers: header,
      })
    }else {
      return new Response(rsp.body, {
        status: rsp.status,
        headers: rsp.headers,
      })
    }
  }

  // handle api
  if(/^\/api/.test(url.pathname)) {
    url.protocol = 'https:'
    url.pathname = url.pathname.replace(/\api/,"")
    url.host = "api.ruguoapp.com"
    const rsp = await fetch(url.href)
    return new Response(rsp.body, {
        status: rsp.status,
        headers: rsp.headers,
    })
  }

  // handle favicon
  if(url.pathname==="/favicon") {
    return new Response("",{
      status: 404,
    }) 
  }

  // handle page redirection
  if(url.pathname!=("/"+username)) {
    return new Response("",{
      status: 302,
      headers: {
        Location: "/"+username
      }
    })
  }

  // fetch original html
  const original_response = await fetch('https://jike.city/'+username)

  const new_response_headers = new Headers(original_response.headers)
  new_response_headers.set('access-control-allow-origin', '*')
  new_response_headers.set('access-control-allow-credentials', true)

  let original_text = null

  const content_type = new_response_headers.get('content-type')
  if (content_type.includes('text/html')) {
    const text = await original_response.text()
    original_text = text.replaceAll(`https://static.codefuture.top`, `/static`)
  } else {
    original_text = original_response.body
  }

  return new Response(original_text, {
    status: original_response.status,
    headers: new_response_headers,
  })
}

Finally, let's try our custom domain https://yp.sorcererxw.com/ and enjoy the sense of accomplishment!

Summary

The above analysis is actually a general process of using Cloudflare Worker to implement reverse proxy. With the same process, we can set up custom domain names for the vast majority of websites. For example, the widely appreciated project Fruition, which configures custom domain names for Notion through Cloudflare. After carefully analyzing its source code, you can find that it also hijacks and injects a large amount of Notion's entire loading process to achieve a good reverse proxy effect.

Fruition - Build Your Next Website With Notion, For Free
Perfect for your portfolio, blog, landing page, or business site. Features: pretty links, custom domains, Google Fonts, SEO support, script injection.
https://fruitionsite.com/