koajax
v3.0.3
Published
HTTP Client based on Koa-like middlewares
Downloads
488
Maintainers
Readme
KoAJAX
HTTP Client based on Koa-like middlewares
Feature
Request Body
Automatic Serialized types:
- Pure text:
string
- Form encoding:
URLSearchParams
,FormData
- DOM object:
Node
- JSON object:
Object
- Binary data:
Blob
,ArrayBuffer
, TypedArray,DataView
- Stream object:
ReadableStream
Response Body
Automatic Parsed type:
- HTML/XML:
Document
- JSON:
Object
- Binary data:
ArrayBuffer
Usage
Browser
Installation
npm install koajax
index.html
<head>
<script src="https://polyfill.web-cell.dev/feature/Regenerator.js"></script>
<script src="https://polyfill.web-cell.dev/feature/ECMAScript.js"></script>
<script src="https://polyfill.web-cell.dev/feature/TextEncoder.js"></script>
<script src="https://polyfill.web-cell.dev/feature/AbortController.js"></script>
<script src="https://polyfill.web-cell.dev/feature/Stream.js"></script>
</head>
Node.js
Installation
npm install koajax jsdom
index.ts
import { HTTPClient } from 'koajax';
import { polyfill } from 'koajax/source/polyfill'
const origin = 'https://your-target-origin.com';
polyfill(origin).then(() => {
const client = new HTTPClient({
baseURI: `${origin}/api`,
responseType: 'json'
});
const { body } = await client.get('test/interface');
console.log(body);
});
Execution
npx tsx index.ts
Non-polyfillable runtimes
- https://github.com/idea2app/KoAJAX-Taro-adapter
Example
RESTful API with Token-based Authorization
import { HTTPClient } from 'koajax';
var token = '';
export const client = new HTTPClient().use(
async ({ request: { method, path, headers }, response }, next) => {
if (token) headers['Authorization'] = 'token ' + token;
await next();
if (method === 'POST' && path.startsWith('/session'))
token = response.headers.Token;
}
);
client.get('/path/to/your/API').then(console.log);
Up/Download files
Single HTTP request based on XMLHTTPRequest progress
events
(based on Async Generator)
import { request } from 'koajax';
document.querySelector('input[type="file"]').onchange = async ({
target: { files }
}) => {
for (const file of files) {
const { upload, download, response } = request({
method: 'POST',
path: '/files',
body: file,
responseType: 'json'
});
for await (const { loaded } of upload)
console.log(`Upload ${file.name} : ${(loaded / file.size) * 100}%`);
const { body } = await response;
console.log(`Upload ${file.name} : ${body.url}`);
}
};
Multiple HTTP requests based on Range
header
npm i native-file-system-adapter # Web standard API polyfill
import { showSaveFilePicker } from 'native-file-system-adapter';
import { HTTPClient } from 'koajax';
const bufferClient = new HTTPClient({ responseType: 'arraybuffer' });
document.querySelector('#download').onclick = async () => {
const fileURL = 'https://your.server/with/Range/header/supported/file.zip';
const suggestedName = new URL(fileURL).pathname.split('/').pop();
const fileHandle = await showSaveFilePicker({ suggestedName });
const writer = await fileHandle.createWritable(),
stream = bufferClient.download(fileURL);
try {
for await (const { total, loaded, percent, buffer } of stream) {
await writer.write(buffer);
console.table({ total, loaded, percent });
}
window.alert(`File ${fileHandle.name} downloaded successfully!`);
} finally {
await writer.close();
}
};
Global Error fallback
npm install browser-unhandled-rejection # Web standard API polyfill
import { auto } from 'browser-unhandled-rejection';
import { HTTPError } from 'koajax';
auto();
window.addEventListener('unhandledrejection', ({ reason }) => {
if (!(reason instanceof HTTPError)) return;
const { message } = reason.response.body;
if (message) window.alert(message);
});
Read Files
(based on Async Generator)
import { readAs } from 'koajax';
document.querySelector('input[type="file"]').onchange = async ({
target: { files }
}) => {
for (const file of files) {
const { progress, result } = readAs(file, 'dataURL');
for await (const { loaded } of progress)
console.log(
`Loading ${file.name} : ${(loaded / file.size) * 100}%`
);
const URI = await result;
console.log(`Loaded ${file.name} : ${URI}`);
}
};