expo-popcore-old/utils/cookie-encoding.ts

162 lines
4.1 KiB
TypeScript

/**
* Cookie编码处理工具
* 解决特殊字符在Cookie中的编码问题
*/
/**
* 安全编码Cookie值
* 使用encodeURIComponent确保特殊字符正确编码
*
* @param value 原始值
* @returns 编码后的值
*/
export function encodeCookieValue(value: string): string {
if (!value) return '';
try {
// 使用encodeURIComponent编码所有特殊字符
return encodeURIComponent(value);
} catch (error) {
console.error('Cookie值编码失败:', error);
return value; // 编码失败时返回原值
}
}
/**
* 安全解码Cookie值
* 使用decodeURIComponent解码编码的值
*
* @param encodedValue 编码后的值
* @returns 解码后的原始值
*/
export function decodeCookieValue(encodedValue: string): string {
if (!encodedValue) return '';
try {
// 使用decodeURIComponent解码
return decodeURIComponent(encodedValue);
} catch (error) {
console.error('Cookie值解码失败:', error);
// 解码失败时,可能值已经未编码,返回原值
return encodedValue;
}
}
/**
* 批量编码Cookie对象中的所有值
*
* @param cookieObj Cookie对象 {key: value}
* @returns 编码后的Cookie对象
*/
export function encodeCookieObject(cookieObj: Record<string, string>): Record<string, string> {
const encoded: Record<string, string> = {};
for (const [key, value] of Object.entries(cookieObj)) {
encoded[key] = encodeCookieValue(value);
}
return encoded;
}
/**
* 批量解码Cookie对象中的所有值
*
* @param encodedCookieObj 编码的Cookie对象
* @returns 解码后的Cookie对象
*/
export function decodeCookieObject(encodedCookieObj: Record<string, string>): Record<string, string> {
const decoded: Record<string, string> = {};
for (const [key, value] of Object.entries(encodedCookieObj)) {
decoded[key] = decodeCookieValue(value);
}
return decoded;
}
/**
* 安全解析包含编码值的Cookie字符串
*
* @param cookieString Cookie字符串
* @returns 解析后的Cookie对象
*/
export function parseEncodedCookieString(cookieString: string): Record<string, string> {
if (!cookieString) return {};
const cookies: Record<string, string> = {};
// 分割多个Cookie对
const cookiePairs = cookieString.split(';').map(pair => pair.trim());
for (const pair of cookiePairs) {
if (!pair) continue;
const [key, ...valueParts] = pair.split('=');
if (!key) continue;
const value = valueParts.join('=');
cookies[key] = decodeCookieValue(value);
}
return cookies;
}
/**
* 创建包含编码值的Cookie字符串
*
* @param cookieObj Cookie对象
* @returns 编码后的Cookie字符串
*/
export function createEncodedCookieString(cookieObj: Record<string, string>): string {
const encodedPairs: string[] = [];
for (const [key, value] of Object.entries(cookieObj)) {
const encodedValue = encodeCookieValue(value);
encodedPairs.push(`${key}=${encodedValue}`);
}
return encodedPairs.join('; ');
}
/**
* 检查字符串是否包含特殊字符
*
* @param value 要检查的字符串
* @returns 是否包含需要编码的字符
*/
export function hasSpecialChars(value: string): boolean {
// 检查是否包含需要编码的特殊字符
const specialChars = /[^\w\-._~!$&'()*+,;=:@\/]/;
return specialChars.test(value);
}
/**
* 智能编码:仅对包含特殊字符的值进行编码
*
* @param value 要编码的值
* @returns 编码后的值
*/
export function smartEncodeCookieValue(value: string): string {
if (!value) return '';
// 如果包含特殊字符则编码,否则返回原值
return hasSpecialChars(value) ? encodeCookieValue(value) : value;
}
/**
* 智能解码:尝试解码,失败则返回原值
*
* @param encodedValue 可能编码的值
* @returns 解码后的值
*/
export function smartDecodeCookieValue(encodedValue: string): string {
if (!encodedValue) return '';
// 尝试解码,如果解码后的值与原值相同,可能说明没有编码过
try {
const decoded = decodeCookieValue(encodedValue);
return decoded;
} catch (error) {
return encodedValue;
}
}