修复页面加载bug
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
|
import Script from "next/script";
|
||||||
import { AppShell } from "@/components/app-shell";
|
import { AppShell } from "@/components/app-shell";
|
||||||
|
import { randomUUIDPolyfillScript } from "@/lib/client/random-uuid-polyfill";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
@@ -11,6 +13,11 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|||||||
return (
|
return (
|
||||||
<html lang="zh-CN">
|
<html lang="zh-CN">
|
||||||
<body>
|
<body>
|
||||||
|
<Script
|
||||||
|
id="random-uuid-polyfill"
|
||||||
|
strategy="beforeInteractive"
|
||||||
|
dangerouslySetInnerHTML={{ __html: randomUUIDPolyfillScript }}
|
||||||
|
/>
|
||||||
<AppShell>{children}</AppShell>
|
<AppShell>{children}</AppShell>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
56
lib/client/random-uuid-polyfill.ts
Normal file
56
lib/client/random-uuid-polyfill.ts
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
export const randomUUIDPolyfillScript = `
|
||||||
|
(function () {
|
||||||
|
var root = typeof globalThis !== "undefined" ? globalThis : window;
|
||||||
|
var cryptoObject = root.crypto || root.msCrypto;
|
||||||
|
if (cryptoObject && typeof cryptoObject.randomUUID === "function") return;
|
||||||
|
if (!cryptoObject) {
|
||||||
|
cryptoObject = {};
|
||||||
|
try {
|
||||||
|
Object.defineProperty(root, "crypto", {
|
||||||
|
configurable: true,
|
||||||
|
value: cryptoObject
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
root.crypto = cryptoObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var getRandomValues = typeof cryptoObject.getRandomValues === "function"
|
||||||
|
? cryptoObject.getRandomValues.bind(cryptoObject)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
function byteToHex(byte) {
|
||||||
|
return (byte + 256).toString(16).slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createRandomUUID() {
|
||||||
|
var bytes = new Uint8Array(16);
|
||||||
|
if (getRandomValues) {
|
||||||
|
getRandomValues(bytes);
|
||||||
|
} else {
|
||||||
|
for (var index = 0; index < bytes.length; index += 1) {
|
||||||
|
bytes[index] = Math.floor(Math.random() * 256);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bytes[6] = (bytes[6] & 15) | 64;
|
||||||
|
bytes[8] = (bytes[8] & 63) | 128;
|
||||||
|
return (
|
||||||
|
byteToHex(bytes[0]) + byteToHex(bytes[1]) + byteToHex(bytes[2]) + byteToHex(bytes[3]) + "-" +
|
||||||
|
byteToHex(bytes[4]) + byteToHex(bytes[5]) + "-" +
|
||||||
|
byteToHex(bytes[6]) + byteToHex(bytes[7]) + "-" +
|
||||||
|
byteToHex(bytes[8]) + byteToHex(bytes[9]) + "-" +
|
||||||
|
byteToHex(bytes[10]) + byteToHex(bytes[11]) + byteToHex(bytes[12]) +
|
||||||
|
byteToHex(bytes[13]) + byteToHex(bytes[14]) + byteToHex(bytes[15])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Object.defineProperty(cryptoObject, "randomUUID", {
|
||||||
|
configurable: true,
|
||||||
|
value: createRandomUUID
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
cryptoObject.randomUUID = createRandomUUID;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
`;
|
||||||
32
tests/random-uuid-polyfill.test.ts
Normal file
32
tests/random-uuid-polyfill.test.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import vm from "node:vm";
|
||||||
|
import { randomUUIDPolyfillScript } from "@/lib/client/random-uuid-polyfill";
|
||||||
|
|
||||||
|
describe("client randomUUID polyfill", () => {
|
||||||
|
it("defines crypto.randomUUID when crypto is missing", () => {
|
||||||
|
const context = {};
|
||||||
|
|
||||||
|
vm.runInNewContext(randomUUIDPolyfillScript, context);
|
||||||
|
|
||||||
|
expect(context.crypto.randomUUID()).toMatch(
|
||||||
|
/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("defines crypto.randomUUID when only getRandomValues is available", () => {
|
||||||
|
const context = {
|
||||||
|
crypto: {
|
||||||
|
getRandomValues(bytes: Uint8Array) {
|
||||||
|
for (let index = 0; index < bytes.length; index += 1) bytes[index] = index;
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
vm.runInNewContext(randomUUIDPolyfillScript, context);
|
||||||
|
|
||||||
|
expect(context.crypto.randomUUID()).toMatch(
|
||||||
|
/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user