首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

JS escape 與 PHP urlencode 跨語言 URL 編碼解碼完整解決方案

     編輯:PHP 相關知識

前端使用 JavaScript escape() 編碼中文參數傳遞給 PHP 時,PHP 內建 urldecode() 或 base64_decode() 無法正確還原,因為 escape() 產生 %uXXXX 格式(Unicode 代碼點),而非標準 Percent-encoding。本文提供雙向轉換函數,解決跨語言編碼不一致問題。

問題重現

// JS 端
window.open('product_list.php?p_sort=' + escape('PHP開發資源網'));
// 產生:product_list.php?p_sort=PHP%u5F00%u53D1%u8D44%u6E90%u7F51

// PHP 端直接 urldecode 失敗,得到亂碼

PHP 解碼 JS escape 字串

手動解析 %uXXXX 與標準 %XX,並依 Unicode 代碼點重組 UTF-8 位元組,最後視需求轉為目標編碼(如 GB2312)。

function js_unescape($str) {
    $ret = '';
    $len = strlen($str);
    for ($i = 0; $i < $len; $i++) {
        if ($str[$i] === '%' && $str[$i+1] === 'u') {
            $val = hexdec(substr($str, $i+2, 4));
            if ($val < 0x7f) {
                $ret .= chr($val);
            } elseif ($val < 0x800) {
                $ret .= chr(0xc0 | ($val >> 6)) . chr(0x80 | ($val & 0x3f));
            } else {
                $ret .= chr(0xe0 | ($val >> 12))
                     . chr(0x80 | (($val >> 6) & 0x3f))
                     . chr(0x80 | ($val & 0x3f));
            }
            $i += 5;
        } elseif ($str[$i] === '%') {
            $ret .= urldecode(substr($str, $i, 3));
            $i += 2;
        } else {
            $ret .= $str[$i];
        }
    }
    return $ret;
}

// 使用:先 js_unescape 再 iconv 轉編碼
$decoded = iconv('utf-8', 'gb2312', js_unescape($_REQUEST['p_sort']));

PHP 端模擬 JS escape 編碼(反向操作)

若需在 PHP 產生與 JS escape() 相容的字串(如組 URL 給前端),可用此函數。

function phpescape($str) {
    $returnString = '';
    $len = strlen($str);
    for ($i = 0; $i < $len; $i++) {
        $ord = ord($str[$i]);
        if ($ord >= 127) { // 多位元組字元(假設輸入為 GB2312)
            // 取兩個位元組轉 UCS-2 再轉 hex
            $tmp = bin2hex(iconv('gb2312', 'ucs-2', substr($str, $i, 2)));
            // Windows 小端序可能需調換位序:$tmp = substr($tmp,2,2).substr($tmp,0,2);
            $returnString .= '%u' . $tmp;
            $i++; // 消耗兩個位元組
        } else {
            $returnString .= '%' . dechex($ord);
        }
    }
    return $returnString;
}

最佳實踐建議

  • 新專案請統一使用 encodeURIComponent() (JS) + urldecode() (PHP),皆遵循 RFC 3986 標準,無需額外轉換。
  • 舊系統維護時,採用上述函數橋接,並在資料庫儲存前統一轉為 UTF-8。
  • 注意 escape() 已棄用,現代瀏覽器仍支援但不建議新增使用。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved