fix utm unicode
This commit is contained in:
parent
7f80767333
commit
5bef4efbf1
@ -3,8 +3,18 @@ import { NextRequest, NextResponse } from "next/server";
|
|||||||
import { createPaymentCheckout } from "@/entities/payment/api";
|
import { createPaymentCheckout } from "@/entities/payment/api";
|
||||||
import { ROUTES } from "@/shared/constants/client-routes";
|
import { ROUTES } from "@/shared/constants/client-routes";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert base64 string to bytes (handles UTF-8 properly)
|
||||||
|
* MDN recommended approach: https://developer.mozilla.org/en-US/docs/Web/API/Window/btoa#unicode_strings
|
||||||
|
*/
|
||||||
|
function base64ToBytes(base64: string): Uint8Array {
|
||||||
|
const binString = atob(base64);
|
||||||
|
return Uint8Array.from(binString, (m) => m.codePointAt(0) ?? 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode URL-safe base64 state parameter to UTM object
|
* Decode URL-safe base64 state parameter to UTM object
|
||||||
|
* Supports UTF-8 encoded content (e.g., utm_campaign=夏セール)
|
||||||
*/
|
*/
|
||||||
function decodeStateParam(state: string): Record<string, string> | undefined {
|
function decodeStateParam(state: string): Record<string, string> | undefined {
|
||||||
if (!state) return undefined;
|
if (!state) return undefined;
|
||||||
@ -16,7 +26,9 @@ function decodeStateParam(state: string): Record<string, string> | undefined {
|
|||||||
while (base64.length % 4) {
|
while (base64.length % 4) {
|
||||||
base64 += "=";
|
base64 += "=";
|
||||||
}
|
}
|
||||||
const json = atob(base64);
|
// Decode base64 to bytes, then decode UTF-8
|
||||||
|
const bytes = base64ToBytes(base64);
|
||||||
|
const json = new TextDecoder().decode(bytes);
|
||||||
return JSON.parse(json);
|
return JSON.parse(json);
|
||||||
} catch {
|
} catch {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
@ -61,17 +61,30 @@ export const getCurrentQueryParams = (): Record<string, string> => {
|
|||||||
return utmParams;
|
return utmParams;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert bytes to base64 string (handles UTF-8 properly)
|
||||||
|
* MDN recommended approach: https://developer.mozilla.org/en-US/docs/Web/API/Window/btoa#unicode_strings
|
||||||
|
*/
|
||||||
|
const bytesToBase64 = (bytes: Uint8Array): string => {
|
||||||
|
const binString = Array.from(bytes, (byte) =>
|
||||||
|
String.fromCodePoint(byte)
|
||||||
|
).join("");
|
||||||
|
return btoa(binString);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode params as base64 JSON for state parameter
|
* Encode params as base64 JSON for state parameter
|
||||||
* Uses URL-safe base64 encoding
|
* Uses URL-safe base64 encoding with UTF-8 support
|
||||||
|
* Handles Unicode characters (e.g., utm_campaign=夏セール)
|
||||||
*/
|
*/
|
||||||
export const encodeStateParam = (params: Record<string, string>): string => {
|
export const encodeStateParam = (params: Record<string, string>): string => {
|
||||||
if (Object.keys(params).length === 0) return "";
|
if (Object.keys(params).length === 0) return "";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const json = JSON.stringify(params);
|
const json = JSON.stringify(params);
|
||||||
// Use btoa for base64, replace unsafe chars for URL
|
// Encode string as UTF-8 bytes, then convert to base64
|
||||||
const base64 = btoa(json)
|
const bytes = new TextEncoder().encode(json);
|
||||||
|
const base64 = bytesToBase64(bytes)
|
||||||
.replace(/\+/g, "-")
|
.replace(/\+/g, "-")
|
||||||
.replace(/\//g, "_")
|
.replace(/\//g, "_")
|
||||||
.replace(/=+$/, "");
|
.replace(/=+$/, "");
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user