无需数据库,如何将角色构建器网站状态保存为可分享链接?
Hey there! Awesome idea for your upcoming game's character builder—going database-free is totally feasible for this use case, and it keeps things lightweight and easy to maintain. Let’s walk through the most practical approach that aligns with your workflow: serializing character data into shareable URL parameters.
How It Works
The core idea is to convert all your user’s character choices (attribute points, selected skills, etc.) into a compact, URL-safe string, then append that string as a query parameter to your page’s URL. When someone clicks the shared link, your page reads that parameter, decodes the data, and reconstructs the character build automatically.
Step-by-Step Implementation
1. Collect & Serialize Character Data
When the user clicks a "Save & Share" button, gather all the relevant character data from your divs/table elements. Convert this data into a JSON object, then encode it to make it safe for URLs.
Example code snippet:
// Grab current character state from the page function collectCharacterData() { return { attributes: { strength: document.getElementById("stat-strength").textContent, dexterity: document.getElementById("stat-dexterity").textContent, intelligence: document.getElementById("stat-intelligence").textContent }, selectedSkills: Array.from(document.querySelectorAll(".skill.active")) .map(skill => skill.dataset.skillId) }; } // Generate the encoded share string function encodeBuildData() { const characterData = collectCharacterData(); const jsonString = JSON.stringify(characterData); // Use encodeURIComponent to ensure special characters are URL-safe return encodeURIComponent(jsonString); }
2. Generate & Copy the Share Link
Take the encoded data and append it as a query parameter (like ?build=) to your page’s base URL. Then let the user copy this link to share.
Example:
function createShareLink() { const encodedData = encodeBuildData(); const shareUrl = `${window.location.origin}${window.location.pathname}?build=${encodedData}`; // Copy link to clipboard (modern browsers support this) navigator.clipboard.writeText(shareUrl) .then(() => alert("Share link copied to clipboard!")) .catch(err => console.error("Failed to copy link:", err)); } // Attach this function to your "Share" button document.getElementById("btn-share").addEventListener("click", createShareLink);
3. Load the Character from the Shared Link
When someone opens the shared URL, your page checks for the build query parameter, decodes it, and updates the page elements to match the saved character state.
Example:
function loadSharedBuild() { const urlParams = new URLSearchParams(window.location.search); const encodedBuild = urlParams.get("build"); if (!encodedBuild) return; // No build data to load try { const decodedJson = decodeURIComponent(encodedBuild); const characterData = JSON.parse(decodedJson); // Update attribute stats document.getElementById("stat-strength").textContent = characterData.attributes.strength; document.getElementById("stat-dexterity").textContent = characterData.attributes.dexterity; document.getElementById("stat-intelligence").textContent = characterData.attributes.intelligence; // Activate selected skills characterData.selectedSkills.forEach(skillId => { const skillElement = document.querySelector(`.skill[data-skill-id="${skillId}"]`); if (skillElement) skillElement.classList.add("active"); }); } catch (error) { console.error("Failed to load shared build:", error); alert("Invalid character build link!"); } } // Run this when the page loads window.addEventListener("DOMContentLoaded", loadSharedBuild);
Handling Larger Character Data
URLs have a maximum length limit (usually 2000-8000 characters depending on the browser). If your character data gets complex (like a huge skill tree), you can compress the JSON string to save space. Libraries like lz-string work great for this—they can shrink your data by 50-70% without losing information.
Example with compression:
// After installing lz-string (via npm or CDN) import lzString from "lz-string"; // Encode with compression function encodeBuildData() { const characterData = collectCharacterData(); const jsonString = JSON.stringify(characterData); const compressed = lzString.compressToEncodedURIComponent(jsonString); return compressed; } // Decode with compression function loadSharedBuild() { const urlParams = new URLSearchParams(window.location.search); const compressedBuild = urlParams.get("build"); if (!compressedBuild) return; try { const decodedJson = lzString.decompressFromEncodedURIComponent(compressedBuild); const characterData = JSON.parse(decodedJson); // ... update page elements as before ... } catch (error) { // Handle errors } }
Why This Works for Your Use Case
- No database required: Everything happens client-side—you don’t need to set up any backend infrastructure.
- Direct shareable links: Users get a single URL that instantly loads their build, just like the builder you referenced.
- Simple to implement: The code is straightforward and fits with your existing div/table-based layout.
内容的提问来源于stack exchange,提问作者tharid

