JHipster dataUtils.downloadFile处理非ASCII字符报错求助
Let's break down why you're hitting that Failed to execute 'atob' on 'Window' error and how to fix it cleanly:
The Root Cause
JHipster's built-in dataUtils.downloadFile likely relies on the browser's native atob() function to decode base64 content. The problem? atob() and its counterpart btoa() only work with ASCII characters (Unicode code points 0-127). When you pass base64 encoded from UTF-8 content (which includes characters outside the ASCII range), atob() chokes because it can't parse those non-ASCII bytes correctly. Your workaround of replacing UTF-8 characters with ASCII is tedious, so let's look at better solutions.
Solution 1: Bypass Base64 Entirely (Recommended)
Since you're working with JSON text content, you don't need to go through base64 encoding at all. Instead, create a Blob directly from your UTF-8 string and trigger a download. This avoids the atob()/btoa() limitations entirely.
First, add a custom download function to your component/service:
downloadUtf8File(contentType: string, content: string, fileName: string): void { // Create a Blob with UTF-8 encoding (default for string inputs) const blob = new Blob([content], { type: contentType }); const url = window.URL.createObjectURL(blob); // Create a temporary anchor tag to trigger download const downloadLink = document.createElement('a'); downloadLink.href = url; downloadLink.download = `${fileName}.json`; // Add file extension for clarity document.body.appendChild(downloadLink); downloadLink.click(); // Clean up resources window.URL.revokeObjectURL(url); document.body.removeChild(downloadLink); }
Then update your existing download method to use this function:
download(appliance: Appliance): void { const applianceObj = JSON.parse(appliance.troubleShooting); const prettyPrinted = JSON.stringify(applianceObj, null, 2); // Skip base64 encoding entirely this.downloadUtf8File('application/json', prettyPrinted, appliance.applianceType); }
Solution 2: Patch JHipster's dataUtils to Support UTF-8
If you want to keep using dataUtils.downloadFile, you can modify its internal logic to handle UTF-8 base64 content. Here's how to adjust the decoding step:
- Locate the
dataUtilsservice (usually insrc/main/webapp/app/shared/util/data-util.service.ts). - Find the part where it decodes base64 (likely using
atob()). Replace that section with:
// Replace the existing base64 decoding logic with this UTF-8 compatible version const decodedBase64 = atob(base64Data); const utf8Content = decodeURIComponent( decodedBase64.split('').map(char => { return '%' + ('00' + char.charCodeAt(0).toString(16)).slice(-2); }).join('') ); const blob = new Blob([utf8Content], { type: contentType });
This converts the decoded ASCII bytes back into valid UTF-8 content using decodeURIComponent, which handles the extended character range properly.
Why This Works
- Blobs natively support UTF-8 strings, so creating a Blob directly from your formatted JSON avoids any encoding/decoding headaches.
- The patched
dataUtilslogic fixes theatob()limitation by converting the decoded bytes into UTF-8 via URI encoding, which safely handles all Unicode characters.
内容的提问来源于stack exchange,提问作者dharam

