如何基于外部重定向实现房产广告链接有效性校验逻辑?
Great idea leveraging the redirect behavior to detect inactive ads! Your approach is solid—we can absolutely implement server-side redirect tracking to prevent users from landing on competitor pages. Here's a step-by-step breakdown tailored to your stack:
Core Concept
We'll create a server-side endpoint that takes a target estate URL, sends a request to it, follows all redirects, and checks if the final destination matches the competitor's page. Then, in your EJS templates, we'll hook into link clicks to query this endpoint first, only allowing the redirect if the ad is active.
Step 1: Add a Link-Checking Endpoint to Express
First, we'll use a HTTP client (I'll use axios here, but node-fetch works too) to send a request and track redirects. Make sure to install the dependency first:
npm install axios
Then add this route to your Express app:
const express = require('express'); const axios = require('axios'); const router = express.Router(); // Define the competitor redirect URL we need to watch for const COMPETITOR_REDIRECT_URL = "https://domain.xx/estate-for-rent/city/"; router.post('/check-estate-link', async (req, res) => { const targetUrl = req.body.url; if (!targetUrl) { return res.status(400).json({ valid: false, message: "No URL provided" }); } try { // Send a HEAD request (lighter than GET) to follow redirects const response = await axios.head(targetUrl, { maxRedirects: 5, // Limit redirects to avoid infinite loops validateStatus: (status) => status >= 200 && status < 400, // Accept successful redirects }); // Check if the final URL matches the competitor's page const isCompetitorRedirect = response.config.url === COMPETITOR_REDIRECT_URL; res.json({ valid: !isCompetitorRedirect, message: isCompetitorRedirect ? "This ad is no longer available" : "Ad is active" }); } catch (error) { // Handle errors (e.g., URL is invalid, timeout) console.error("Error checking link:", error.message); res.json({ valid: false, message: "Could not verify ad status" }); } }); module.exports = router;
Don't forget to mount this router in your main app file:
app.use('/', require('./routes/linkChecker'));
Step 2: Update EJS Templates to Use the Endpoint
Modify your estate links in EJS to trigger a check before redirecting. We'll use vanilla JavaScript for this (no extra libraries needed):
<!-- Example estate link in your EJS template --> <a href="<%= estate.link %>" class="estate-link" data-url="<%= estate.link %>" > <%= estate.title %> </a> <script> // Add click handler to all estate links document.querySelectorAll('.estate-link').forEach(link => { link.addEventListener('click', async (e) => { e.preventDefault(); // Block default redirect first const targetUrl = link.dataset.url; try { // Send request to our server-side endpoint const response = await fetch('/check-estate-link', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ url: targetUrl }), }); const result = await response.json(); if (result.valid) { // Ad is active—proceed to redirect window.location.href = targetUrl; } else { // Ad is inactive—show user a message alert(result.message); // Optionally: Disable the link visually link.classList.add('disabled'); link.style.pointerEvents = 'none'; } } catch (error) { console.error("Error verifying ad:", error); alert("Sorry, we couldn't check this ad's status right now."); } }); }); </script>
Step 3: Optimizations & Considerations
- Caching: To avoid spamming the external site with requests (and speed up checks), add a cache layer (e.g., using
node-cache) to store results for 5-15 minutes. This reduces server load and prevents potential IP blocking.const NodeCache = require('node-cache'); const linkCache = new NodeCache({ stdTTL: 900 }); // Cache for 15 minutes // In the /check-estate-link endpoint: const cachedResult = linkCache.get(targetUrl); if (cachedResult) { return res.json(cachedResult); } // After getting the result: linkCache.set(targetUrl, { valid: !isCompetitorRedirect, message: ... }); - HEAD vs GET: Using
HEADrequests is more efficient since we only need headers (not the full page content). If the external site blocks HEAD requests, switch to aGETrequest withresponseType: 'stream'to avoid downloading the entire page. - Error Handling: Add timeouts to the axios request to prevent hanging:
await axios.head(targetUrl, { maxRedirects: 5, validateStatus: ..., timeout: 5000, // 5-second timeout }); - Server-Side Pre-Rendering: If you prefer to check links during EJS rendering (instead of on click), you can pre-fetch the status in your route handler and pass it to the EJS template. This works well if ads don't change too frequently, but real-time checks are better for dynamic content.
This setup ensures users never land on competitor pages when clicking inactive ads, while keeping the experience smooth for active ones. Let me know if you need help tweaking any part!
内容的提问来源于stack exchange,提问作者Christoffer Corfield Aakre

