如何为JavaScript生成的动态内容页面设置唯一URL?
Problem Breakdown
Right now, your code uses window.open("", '_blank') which opens a blank page with the default about:blank URL. To get those clean, unique URLs like www.site-domain.com/site-1.php, we have two feasible solutions tailored for different scenarios:
Solution 1: Frontend-only URL Update (Quick Fix, No Refresh Support)
If you just want the address bar to show the custom URL without setting up server-side files, we can use history.pushState() to modify the new window's history after writing the content. Note: this is a frontend trick—if the user refreshes the new page, they'll get a 404 error unless you add server routing later.
Here's the modified JavaScript code:
let sites = [{ "id": 1, "content": "Lorem ipsum 1" }, { "id": 2, "content": "Lorem ipsum 2" }, { "id": 3, "content": "Lorem ipsum 3" } ]; let siteLinks = document.querySelectorAll(".site-link"); siteLinks.forEach((el) => { el.addEventListener("click", () => { // Find the matching site content using the button's text const targetSite = sites.find(site => site.id.toString() === el.innerText); if (!targetSite) return; // Exit if no match is found // Open a blank window const openedWindow = window.open("", '_blank'); // Write the page content to the new window openedWindow.document.write(` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Project Site ${targetSite.id}</title> <link rel="stylesheet" href="css/styles.css"> </head> <body> <div class="content">${targetSite.content}</div> </body> </html>`); // Close the document stream to finish loading properly openedWindow.document.close(); // Update the URL in the new window's address bar const customUrl = `www.site-domain.com/site-${targetSite.id}.php`; openedWindow.history.pushState({}, '', customUrl); }); });
Key Improvements:
- Swapped
filter()forfind(): Since we only need one matching site entry,find()is more efficient and returns the object directly. - Added
document.close(): Ensures the browser recognizes the page as fully loaded, preventing weird loading state issues. - Used
history.pushState(): This modifies the browser's history without reloading the page, making the address bar show your desired URL.
Solution 2: Server-side Routing (Full Functionality, Supports Refreshes)
For a production-ready solution that lets users refresh or bookmark the new pages, you'll need to set up server-side routing. Here's how to do it with PHP:
- Create a reusable PHP entry file (
site.php) that fetches content based on anidparameter:
<?php // Define your content array (you could also pull this from a database) $siteContent = [ 1 => "Lorem ipsum 1", 2 => "Lorem ipsum 2", 3 => "Lorem ipsum 3" ]; $siteId = $_GET['id'] ?? null; $content = $siteContent[$siteId] ?? "Content not found"; ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Project Site <?php echo $siteId; ?></title> <link rel="stylesheet" href="css/styles.css"> </head> <body> <div class="content"><?php echo $content; ?></div> </body> </html>
- Set up URL rewriting to make
site-1.phppoint tosite.php?id=1. For Apache, add this to your.htaccessfile:
RewriteEngine On RewriteRule ^site-(\d+)\.php$ site.php?id=$1 [L]
(For Nginx, you'd add a similar rule in your server configuration.)
- Simplify your frontend code to open the actual URLs directly:
let siteLinks = document.querySelectorAll(".site-link"); siteLinks.forEach((el) => { el.addEventListener("click", () => { const siteId = el.innerText; window.open(`www.site-domain.com/site-${siteId}.php`, '_blank'); }); });
This approach is the standard way to handle dynamic pages on the web—it supports refreshes, bookmarks, and is more maintainable long-term.
内容的提问来源于stack exchange,提问作者High T

