Created
January 12, 2026 21:36
-
-
Save DavraYoung/dc49ded10533aee24383179a3a2a06a0 to your computer and use it in GitHub Desktop.
Export all intercepted HTTP exchanges from HTTP Toolkit to JSON
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * HTTP Toolkit Export Script | |
| * Exports all intercepted HTTP exchanges to JSON | |
| * | |
| * Usage: Paste this entire script into Chrome DevTools console while HTTP Toolkit is open | |
| * | |
| * Tested with: HTTP Toolkit Desktop (2024-2025 versions) | |
| * GitHub: https://github.com/httptoolkit/httptoolkit-ui | |
| */ | |
| (function() { | |
| 'use strict'; | |
| var VERSION = '1.0.0'; | |
| console.log('HTTP Toolkit Export Script v' + VERSION); | |
| console.log('Searching for events store...'); | |
| var findEventsStore = function() { | |
| var elements = document.querySelectorAll('*'); | |
| for (var i = 0; i < elements.length; i++) { | |
| var el = elements[i]; | |
| var keys = Object.keys(el); | |
| for (var j = 0; j < keys.length; j++) { | |
| var key = keys[j]; | |
| if (key.startsWith('__reactFiber') || key.startsWith('__reactInternalInstance')) { | |
| var fiber = el[key]; | |
| var current = fiber; | |
| for (var depth = 0; depth < 100 && current; depth++) { | |
| try { | |
| if (current.memoizedProps && current.memoizedProps.eventsStore) { | |
| return current.memoizedProps.eventsStore; | |
| } | |
| if (current.memoizedState && current.memoizedState.eventsStore) { | |
| return current.memoizedState.eventsStore; | |
| } | |
| } catch(e) {} | |
| current = current.return; | |
| } | |
| } | |
| } | |
| } | |
| return null; | |
| }; | |
| var decodeBody = function(body) { | |
| if (!body) return null; | |
| try { | |
| var raw = body._decoded || body._encoded; | |
| if (!raw) return null; | |
| if (raw instanceof Uint8Array) { | |
| return new TextDecoder('utf-8', { fatal: false }).decode(raw); | |
| } | |
| if (raw.buffer && raw.buffer instanceof ArrayBuffer) { | |
| return new TextDecoder('utf-8', { fatal: false }).decode(raw.buffer); | |
| } | |
| if (typeof raw === 'string') return raw; | |
| return null; | |
| } catch(e) { | |
| return '[decode error: ' + e.message + ']'; | |
| } | |
| }; | |
| var store = findEventsStore(); | |
| if (!store) { | |
| console.error('ERROR: Could not find HTTP Toolkit events store.'); | |
| console.error('Make sure you are running this in HTTP Toolkit Desktop app.'); | |
| console.error('If this persists, the app structure may have changed.'); | |
| return; | |
| } | |
| if (!store.eventsList || !store.eventsList._exchanges) { | |
| console.error('ERROR: Events store found but structure is unexpected.'); | |
| console.error('Available keys:', Object.keys(store)); | |
| if (store.eventsList) { | |
| console.error('eventsList keys:', Object.keys(store.eventsList)); | |
| } | |
| return; | |
| } | |
| var exchanges = Array.from(store.eventsList._exchanges); | |
| if (exchanges.length === 0) { | |
| console.warn('No exchanges found. Intercept some HTTP traffic first.'); | |
| return; | |
| } | |
| console.log('Found ' + exchanges.length + ' exchanges. Processing...'); | |
| var data = []; | |
| var errors = 0; | |
| exchanges.forEach(function(evt, index) { | |
| try { | |
| var item = { | |
| id: evt.id, | |
| request: { | |
| method: evt.request.method, | |
| url: evt.request.url, | |
| protocol: evt.request.protocol, | |
| path: evt.request.path, | |
| httpVersion: evt.request.httpVersion, | |
| headers: evt.request.headers, | |
| body: decodeBody(evt.request.body), | |
| remoteIpAddress: evt.request.remoteIpAddress, | |
| remotePort: evt.request.remotePort | |
| }, | |
| response: null, | |
| timingEvents: evt.timingEvents, | |
| tags: evt.tags | |
| }; | |
| if (evt.response) { | |
| item.response = { | |
| statusCode: evt.response.statusCode, | |
| statusMessage: evt.response.statusMessage, | |
| headers: evt.response.headers, | |
| body: decodeBody(evt.response.body) | |
| }; | |
| } | |
| data.push(item); | |
| } catch(e) { | |
| errors++; | |
| console.warn('Error processing exchange ' + index + ':', e.message); | |
| } | |
| }); | |
| var filename = 'http-toolkit-export-' + new Date().toISOString().slice(0,19).replace(/:/g, '-') + '.json'; | |
| var json = JSON.stringify(data, null, 2); | |
| var blob = new Blob([json], { type: 'application/json' }); | |
| var url = URL.createObjectURL(blob); | |
| var a = document.createElement('a'); | |
| a.href = url; | |
| a.download = filename; | |
| document.body.appendChild(a); | |
| a.click(); | |
| document.body.removeChild(a); | |
| URL.revokeObjectURL(url); | |
| console.log('SUCCESS: Exported ' + data.length + ' exchanges to ' + filename); | |
| if (errors > 0) { | |
| console.warn(errors + ' exchanges had errors and were skipped.'); | |
| } | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment