How to decode URL-encoded and URL query strings in TypeScript

2 Answers

0 votes
/**
 * Decodes a URL-encoded string or query component.
 * Replaces '+' with spaces and decodes percent-encoded characters (%xx).
 * 
 * @param encodedStr - The URL-encoded string to decode.
 * @returns The fully decoded string.
 */
function decodeUrlString(encodedStr: string): string {
    try {
        // Replace '+' with spaces first, as decodeURIComponent treats '+' literally
        const normalizedStr: string = encodedStr.replace(/\+/g, ' ');
        return decodeURIComponent(normalizedStr);
    } catch (error: unknown) {
        if (error instanceof Error) {
            console.error("Decoding error:", error.message);
        }
        return encodedStr;
    }
}

// --- Program Execution ---
if (typeof module !== 'undefined' && require.main === module) {
    // Example 1: Standard URL encoding with special characters
    const sample1: string = "Hello%20World%21%20TypeScript%20%26%20Web";
    console.log("--- Example 1: Standard URL Encoding ---");
    console.log("Encoded:", sample1);
    console.log("Decoded:", decodeUrlString(sample1));

    // Example 2: Form query string fragment encoding (spaces as '+')
    const sample2: string = "Jane+Doe+from+New+York";
    console.log("\n--- Example 2: Form Fragment Encoding ---");
    console.log("Encoded:", sample2);
    console.log("Decoded:", decodeUrlString(sample2));
}


/*
run:

--- Example 1: Standard URL Encoding ---
Encoded: Hello%20World%21%20TypeScript%20%26%20Web
Decoded: Hello World! TypeScript & Web

--- Example 2: Form Fragment Encoding ---
Encoded: Jane+Doe+from+New+York
Decoded: Jane Doe from New York

*/

 



answered 2 hours ago by avibootz
0 votes
/**
 * Parses and decodes a complete URL query string into a typed dictionary object.
 * 
 * @param queryString - The URL query string (with or without leading '?').
 * @returns An object mapping keys to their decoded values or arrays of values.
 */
function parseAndDecodeQuery(queryString: string): Record<string, string | string[]> {
    // Remove leading '?' if present
    const cleanQuery: string = queryString.startsWith('?') ? queryString.slice(1) : queryString;
    
    // URLSearchParams automatically handles decoding and '+' to space conversion
    const params: URLSearchParams = new URLSearchParams(cleanQuery);
    const result: Record<string, string | string[]> = {};

    for (const [key, value] of params.entries()) {
        // Handle multi-value parameters by grouping them into an array
        if (result[key]) {
            const existing = result[key];
            if (Array.isArray(existing)) {
                existing.push(value);
            } else {
                result[key] = [existing, value];
            }
        } else {
            result[key] = value;
        }
    }

    return result;
}

// --- Program Execution ---
if (typeof module !== 'undefined' && require.main === module) {
    const fullQuery: string = "search=typescript+tutorial&category=programming&tag=beginner&tag=frontend";
    
    console.log("--- Full Query String Parsing ---");
    console.log("Original Query:", fullQuery);

    const decodedParams: Record<string, string | string[]> = parseAndDecodeQuery(fullQuery);
    
    console.log("Decoded Object Result:");
    for (const [key, value] of Object.entries(decodedParams)) {
        console.log(`  ${key} ->`, value);
    }
}


/*
run:

--- Full Query String Parsing ---
Original Query: search=typescript+tutorial&category=programming&tag=beginner&tag=frontend
Decoded Object Result:
  search -> typescript tutorial
  category -> programming
  tag -> [ 'beginner', 'frontend' ]

*/

 



answered 2 hours ago by avibootz
...