koajax v3.1.1
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 core-js jsdom
index.ts
import { polyfill } from 'koajax/source/polyfill';
import { HTTPClient } from 'koajax';
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
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}`);
}
};
Single HTTP request based on Fetch duplex
streams
This experimental feature has some limitations.
-import { request } from 'koajax';
+import { requestFetch } from 'koajax';
document.querySelector('input[type="file"]').onchange = async ({
target: { files }
}) => {
for (const file of files) {
- const { upload, download, response } = request({
+ const { upload, download, response } = requestFetch({
method: 'POST',
path: '/files',
+ headers: {
+ 'Content-Type': file.type,
+ 'Content-Length': file.size + ''
+ },
- body: file,
+ body: file.stream(),
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}`);
}
};
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
8 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
11 months ago
11 months ago
1 year ago
11 months ago
11 months ago
1 year ago
11 months ago
11 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago