如何在JavaScript中点击按钮时获取完整控制台输出(含XHR错误)?
Great question—this is totally doable! You’ll need to tackle two key pieces: override native console methods to capture logs/warnings/errors, and hook into XHR/fetch requests to catch their failures. Here’s a step-by-step implementation that covers all your needs:
1. Set Up Storage for Captured Output
First, create a variable to store every piece of console activity we’ll capture:
const consoleLogs = [];
2. Override Native Console Methods
We’ll wrap console.log, console.warn, console.error, and console.info to capture their output while still letting them display in the real browser console:
// Save original console methods so we don't break native behavior const originalLog = console.log; const originalWarn = console.warn; const originalError = console.error; const originalInfo = console.info; // Override log to capture and forward messages console.log = (...args) => { consoleLogs.push({ type: 'log', message: args.join(' ') }); originalLog.apply(console, args); }; // Override warn console.warn = (...args) => { consoleLogs.push({ type: 'warn', message: args.join(' ') }); originalWarn.apply(console, args); }; // Override error (catches console errors including XHR/fetch console warnings) console.error = (...args) => { consoleLogs.push({ type: 'error', message: args.join(' ') }); originalError.apply(console, args); }; // Override info (optional, but captures additional info-level messages) console.info = (...args) => { consoleLogs.push({ type: 'info', message: args.join(' ') }); originalInfo.apply(console, args); };
3. Capture XHR Errors (Network & HTTP Failures)
Native XHR errors might not always trigger console.error, so we’ll monkey-patch the XMLHttpRequest object to catch both network errors and HTTP status errors (like 404/500):
const originalXHR = XMLHttpRequest; XMLHttpRequest = function() { const xhr = new originalXHR(); // Capture network errors const originalOnError = xhr.onerror; xhr.onerror = function(event) { const errorMsg = `XHR Network Error: ${event.target.statusText} - URL: ${event.target.responseURL}`; consoleLogs.push({ type: 'xhr-network-error', message: errorMsg }); if (originalOnError) originalOnError.apply(this, arguments); }; // Capture HTTP errors (status codes >=400) that don't trigger onerror const originalOnLoad = xhr.onload; xhr.onload = function() { if (this.status >= 400) { const errorMsg = `XHR HTTP Error: ${this.status} ${this.statusText} - URL: ${this.responseURL}`; consoleLogs.push({ type: 'xhr-http-error', message: errorMsg }); } if (originalOnLoad) originalOnLoad.apply(this, arguments); }; return xhr; };
4. Capture Fetch Errors
The fetch API only rejects on network failures, so we’ll wrap it to catch both network errors and HTTP status errors:
const originalFetch = fetch; window.fetch = async (...args) => { try { const response = await originalFetch.apply(window, args); // Capture HTTP errors (fetch doesn't reject on these by default) if (!response.ok) { const errorMsg = `Fetch HTTP Error: ${response.status} ${response.statusText} - URL: ${args[0]}`; consoleLogs.push({ type: 'fetch-http-error', message: errorMsg }); } return response; } catch (err) { // Capture network failures const errorMsg = `Fetch Network Error: ${err.message} - URL: ${args[0]}`; consoleLogs.push({ type: 'fetch-network-error', message: errorMsg }); throw err; // Re-throw so the original request code still gets the error } };
5. Add a Button to Export Captured Output
Finally, create a button that converts all stored logs into a readable string (and even lets you download it as a text file):
<button id="exportLogsBtn">Export Full Console Logs</button> <script> document.getElementById('exportLogsBtn').addEventListener('click', () => { // Convert logs array to a formatted string const logString = consoleLogs.map(log => `[${log.type.toUpperCase()}] ${log.message}`).join('\n'); // Log the full string to the console (for testing) console.log('Captured Console Output:\n', logString); // Optional: Download as a text file const blob = new Blob([logString], { type: 'text/plain' }); const url = URL.createObjectURL(blob); const downloadLink = document.createElement('a'); downloadLink.href = url; downloadLink.download = 'console-logs.txt'; downloadLink.click(); URL.revokeObjectURL(url); }); </script>
Quick Notes
- Load this script early in your page (before any other scripts) to capture all logs from the start.
- For complex console outputs (like objects), replace
args.join(' ')withJSON.stringify(args)if you need to preserve detailed object data (it’ll be less human-readable but more complete). - Some browser-blocked errors (like certain CORS issues) will still show up in the native console, and our overridden
console.errorwill capture them automatically.
内容的提问来源于stack exchange,提问作者Nezih

