Now.js Framework Documentation
HttpClient - ไคลเอนต์ HTTP ระดับต่ำ
HttpClient - ไคลเอนต์ HTTP ระดับต่ำ
เอกสารสำหรับ HttpClient ซึ่งเป็นไคลเอนต์ HTTP ระดับต่ำของ Now.js Framework
📋 สารบัญ
- ภาพรวม
- การติดตั้งและนำเข้า
- Exports ทั้งหมด
- คลาส HttpClient
- อินสแตนซ์ http
- อินสแตนซ์ httpthrow
- ยูทิลิตี้ simpleFetch
- ตัวดัก Interceptor
- การป้องกัน csrf
- ฟีเจอร์ด้านความปลอดภัย
- การจัดการข้อผิดพลาด
- ตัวอย่างการใช้งาน
- เอกสารอ้างอิง api
- แนวปฏิบัติที่ดีที่สุด
ภาพรวม
HttpClient เป็น Low-level HTTP Client ที่สร้างจาก Fetch API มีฟีเจอร์ที่ทันสมัยและปลอดภัย เหมาะสำหรับการเรียก API ที่ต้องการการควบคุมระดับต่ำ
ฟีเจอร์หลัก
- ✅ 4 Exports:
HttpClient,http,httpThrow,simpleFetch - ✅ Interceptors: Request และ Response interceptors
- ✅ CSRF Protection: ป้องกัน CSRF attacks
- ✅ Auto Content-Type Detection: ตรวจจับและแปลง response อัตโนมัติ
- ✅ Timeout Support: กำหนด timeout สำหรับ requests
- ✅ Error Handling: จัดการ errors แบบยืดหยุ่น
- ✅ Custom Response Handler: กำหนดวิธีจัดการ response เอง
- ✅ AbortController Support: ยกเลิก requests ได้
- ✅ FormData/Blob/ArrayBuffer Support: รองรับ content types หลากหลาย
การติดตั้งและนำเข้า
HttpClient โหลดมาพร้อมกับ Now.js Framework และพร้อมใช้งานทันทีผ่าน window object:
// ไม่ต้อง import - พร้อมใช้งานทันที
console.log(window.http); // อินสแตนซ์ http
console.log(window.httpThrow); // อินสแตนซ์ httpThrow
console.log(window.simpleFetch); // ยูทิลิตี้ simpleFetch
console.log(window.HttpClient); // คลาส HttpClientExports ทั้งหมด
HttpClient มี 4 exports หลัก ที่ให้ใช้งาน:
| Export | ประเภท | throwOnError | กรณีใช้งาน |
|---|---|---|---|
HttpClient |
คลาส | ตามที่กำหนด | สร้างอินสแตนซ์แบบกำหนดเอง |
http |
อินสแตนซ์ | false |
การใช้งานทั่วไป (โหมดปลอดภัย) |
httpThrow |
อินสแตนซ์ | true |
การใช้งานที่ต้องการให้ throw error |
simpleFetch |
อ็อบเจ็กต์ยูทิลิตี้ | N/A | การใช้งานแบบเบาและรวดเร็ว |
คลาส HttpClient
คอนสตรักเตอร์
สร้าง HttpClient instance ใหม่:
const client = new HttpClient(options);ตัวเลือก
| ตัวเลือก | ประเภท | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|---|
baseURL |
string |
'' |
Base URL สำหรับทุก request |
headers |
object |
{} |
Header เริ่มต้น |
timeout |
number |
30000 |
เวลา timeout หน่วยมิลลิวินาที |
throwOnError |
boolean |
true |
ให้ throw error เมื่อ response ไม่สำเร็จ |
responseHandler |
function |
null |
ฟังก์ชันจัดการ response แบบกำหนดเอง |
csrfCookieName |
string |
'XSRF-TOKEN' |
ชื่อคุกกี้สำหรับ CSRF |
csrfTokenSelector |
string |
'meta[name="csrf-token"]' |
ตัวเลือก CSS สำหรับ meta tag CSRF |
security |
object |
{} |
การตั้งค่าด้านความปลอดภัย |
ตัวอย่างการสร้าง Instance
// อินสแตนซ์พื้นฐาน
const api = new HttpClient({
baseURL: 'https://api.example.com',
timeout: 10000
});
// อินสแตนซ์ที่เปิดใช้การป้องกัน CSRF
const secureApi = new HttpClient({
baseURL: 'https://api.example.com',
security: {
csrf: {
enabled: true,
tokenName: '_token',
headerName: 'X-CSRF-Token'
}
}
});
// อินสแตนซ์ที่กำหนด response handler เอง
const customApi = new HttpClient({
baseURL: 'https://api.example.com',
responseHandler: async (response) => {
const data = await response.json();
return {
success: response.ok,
result: data,
timestamp: Date.now()
};
}
});เมธอด
เมธอด HTTP
// ส่งคำขอแบบ GET
await client.get(url, options);
// ส่งคำขอแบบ POST
await client.post(url, data, options);
// ส่งคำขอแบบ PUT
await client.put(url, data, options);
// ส่งคำขอแบบ DELETE
await client.delete(url, options);
// ส่งคำขอแบบ PATCH
await client.patch(url, data, options);
// ส่งคำขอแบบ HEAD
await client.head(url, options);
// ส่งคำขอแบบ OPTIONS
await client.options(url, options);เมธอดโหมดปลอดภัย (ไม่ throw error)
// ส่ง GET แบบโหมดปลอดภัย
await client.getSafe(url, options);
// ส่ง POST แบบโหมดปลอดภัย
await client.postSafe(url, data, options);
// ส่ง PUT แบบโหมดปลอดภัย
await client.putSafe(url, data, options);
// ส่ง DELETE แบบโหมดปลอดภัย
await client.deleteSafe(url, options);เมธอดอัปโหลด
// อัปโหลดไฟล์เดียว
await client.upload('/api/upload', file);
// อัปโหลดหลายไฟล์
await client.upload('/api/upload', [file1, file2]);
// อัปโหลดพร้อมข้อมูลเพิ่มเติม
await client.upload('/api/upload', files, {
data: {
title: 'My Upload',
category: 'images'
}
});เมธอดปรับแต่งค่า
// ตั้งค่า Base URL
client.setBaseURL('https://api.example.com');
// ตั้งค่า Header เดียวเป็นค่าเริ่มต้น
client.setDefaultHeader('Authorization', 'Bearer token');
// ตั้งค่า Header เริ่มต้นหลายรายการ
client.setDefaultHeaders({
'X-App-Version': '1.0.0',
'X-Device-ID': 'abc123'
});
// ตั้งค่า Timeout (60 วินาที)
client.setTimeout(60000); // 60 วินาที
// ตั้งค่า CSRF Token
client.setCsrfToken('token-value');อินสแตนซ์ http
Instance พร้อมใช้งานที่มี throwOnError: false เหมาะสำหรับการใช้งานทั่วไป
คุณสมบัติ
- ❌ ไม่ throw errors (ต้องตรวจสอบ
response.okเอง) - ✅ มี
timestampและrequestIdใน response - ✅ Auto-parse response ตาม Content-Type
การใช้งาน
// ตัวอย่างคำขอ GET
const response = await http.get('/api/users');
if (response.ok) {
console.log(response.data);
console.log('Timestamp:', response.timestamp);
console.log('Request ID:', response.requestId);
} else {
console.error('Error:', response.statusText);
}
// ตัวอย่างคำขอ POST
const response = await http.post('/api/users', {
name: 'John Doe',
email: 'john@example.com'
});
if (response.ok) {
console.log('Created:', response.data);
}อ็อบเจ็กต์ Response
{
ok: boolean, // true หากสถานะ 200-299
status: number, // รหัสสถานะ HTTP
statusText: string, // ข้อความสถานะ HTTP
data: any, // ข้อมูล response ที่แปลงแล้ว
headers: object, // Header ของ response
url: string, // URL ที่เรียก
timestamp: number, // เวลาที่ตอบกลับ (เฉพาะ http instance)
requestId: string|null // รหัสคำขอจาก header (เฉพาะ http instance)
}อินสแตนซ์ httpThrow
Instance พร้อมใช้งานที่มี throwOnError: true เหมาะสำหรับการใช้งานที่ต้องการ try-catch
คุณสมบัติ
- ✅ Throw
HttpErrorเมื่อ response ไม่สำเร็จ - ✅ มี
timestampและrequestIdใน response - ✅ Return format แตกต่างจาก
httpเล็กน้อย
การใช้งาน
try {
// ตัวอย่างคำขอ GET
const response = await httpThrow.get('/api/users');
console.log(response.data);
console.log('ข้อความ:', response.message);
} catch (error) {
console.error('Error:', error.message);
console.error('Status:', error.status);
console.error('Response:', error.response);
}
// ตัวอย่างคำขอ POST
try {
const response = await httpThrow.post('/api/users', {
name: 'John Doe',
email: 'john@example.com'
});
console.log('สร้างสำเร็จ:', response.data);
} catch (error) {
if (error.status === 422) {
console.error('ข้อมูลไม่ผ่านการตรวจสอบ:', error.response.data);
} else {
console.error('ข้อผิดพลาดจากเซิร์ฟเวอร์:', error.message);
}
}อ็อบเจ็กต์ Response (สำเร็จ)
{
status: number, // รหัสสถานะ HTTP
data: any, // ข้อมูล response ที่แปลงแล้ว
message: string, // ข้อความจากเซิร์ฟเวอร์หรือ statusText
meta: any, // ข้อมูลเสริมจากเซิร์ฟเวอร์ (ถ้ามี)
timestamp: number, // เวลาที่ตอบกลับ
headers: object, // Header ของ response
requestId: string|null // รหัสคำขอจาก header
}อ็อบเจ็กต์ HttpError (Error)
{
name: 'HttpError',
message: string, // ข้อความข้อผิดพลาด
status: number, // รหัสสถานะ HTTP
response: object, // อ็อบเจ็กต์ response แบบเต็ม
timestamp: number // เวลาที่เกิดข้อผิดพลาด
}ยูทิลิตี้ simpleFetch
Lightweight fetch wrapper ที่ออกแบบมาให้ใช้งานง่ายและเบา เหมาะสำหรับการเรียก API แบบง่ายๆ
คุณสมบัติ
- ✅ Zero dependencies (ใช้ fetch API เพียงอย่างเดียว)
- ✅ Auto-parsing response (JSON, Text, Blob)
- ✅ Convenience methods (
.json(),.text(),.postJson()) - ✅ Auto-attach bearer token จาก localStorage
- ✅ Timeout support (default 15 seconds)
- ✅ Method chaining สำหรับ configuration
เมธอด HTTP
เมธอดมาตรฐาน (คืนค่าอ็อบเจ็กต์ response)
// ขอข้อมูลแบบ GET
const response = await simpleFetch.get('/api/users');
if (response.ok) {
console.log(response.data);
}
// ขอข้อมูลแบบ POST
const response = await simpleFetch.post('/api/users', {
name: 'John Doe'
});
// ขอข้อมูลแบบ PUT
const response = await simpleFetch.put('/api/users/1', {
name: 'Jane Doe'
});
// ขอข้อมูลแบบ DELETE
const response = await simpleFetch.delete('/api/users/1');
// ขอข้อมูลแบบ PATCH
const response = await simpleFetch.patch('/api/users/1', {
status: 'active'
});เมธอดแบบสะดวก (คืนค่า data โดยตรง)
// ดึงข้อมูล JSON โดยตรง
const users = await simpleFetch.json('/api/users');
console.log(users); // รายชื่อผู้ใช้หรือ null
// ดึงข้อมูลแบบข้อความโดยตรง
const html = await simpleFetch.text('/api/template');
console.log(html); // สตริง HTML หรือ null
// ส่ง JSON แล้วรับคำตอบโดยตรง
const newUser = await simpleFetch.postJson('/api/users', {
name: 'John Doe'
});
console.log(newUser); // อ็อบเจ็กต์ผู้ใช้ที่สร้างใหม่หรือ nullการอัปโหลดไฟล์
// อัปโหลดไฟล์เดียว
const response = await simpleFetch.upload('/api/upload', file);
// อัปโหลดหลายไฟล์
const response = await simpleFetch.upload('/api/upload', [file1, file2]);
// อัปโหลดพร้อมข้อมูลเพิ่มเติม
const response = await simpleFetch.upload('/api/upload', files, {
title: 'My Photos',
category: 'vacation'
});
// อัปโหลดด้วย FormData
const formData = new FormData();
formData.append('file', file);
formData.append('title', 'Photo');
const response = await simpleFetch.upload('/api/upload', formData);การปรับแต่งค่า
// ตั้งค่า Base URL
simpleFetch.setBaseURL('https://api.example.com');
// ตั้งค่า Header เริ่มต้นหลายรายการ
simpleFetch.setHeaders({
'X-App-Version': '1.0.0',
'X-Device-ID': 'abc123'
});
// ตั้งค่า Header รายตัว
simpleFetch.setHeader('X-Custom-Header', 'value');
// ตั้งค่า Timeout (30 วินาที)
simpleFetch.setTimeout(30000); // 30 วินาที
// ลบ Header
simpleFetch.removeHeader('X-Custom-Header');
// รีเซ็ตการตั้งค่าทั้งหมด
simpleFetch.resetConfig();
// ตัวอย่างการใช้งานแบบ Method Chaining
simpleFetch
.setBaseURL('https://api.example.com')
.setTimeout(10000)
.setHeader('X-App-Version', '1.0.0');การแนบ Bearer Token อัตโนมัติ
simpleFetch จะดึง bearer token จาก localStorage.getItem('auth_token') อัตโนมัติและใส่ใน Authorization header:
// ถ้ามี token ใน localStorage
localStorage.setItem('auth_token', 'your-token');
// simpleFetch จะใส่ header นี้อัตโนมัติ:
// Authorization: Bearer your-token
const response = await simpleFetch.get('/api/user/profile');อ็อบเจ็กต์ Response
{
ok: boolean, // true หากสถานะ 200-299
status: number, // รหัสสถานะ HTTP
statusText: string, // ข้อความสถานะ HTTP
data: any, // ข้อมูลที่แปลงแล้ว (หรือ null)
headers: object, // Header ของ response
url: string, // URL ที่เรียก
error: Error // อ็อบเจ็กต์ข้อผิดพลาด (ถ้ามี)
}ตัวดัก Interceptor
Interceptors ช่วยให้คุณสามารถแก้ไข request หรือ response ก่อนที่จะส่งหรือรับ
ตัวดักฝั่ง Request
แก้ไข request config ก่อนส่ง request:
// เพิ่ม request interceptor
const removeInterceptor = http.addRequestInterceptor(config => {
// แก้ไข config
config.headers['X-Timestamp'] = Date.now();
config.headers['X-User-Agent'] = navigator.userAgent;
// ต้อง return config
return config;
});
// ลบ interceptor
removeInterceptor();ตัวดักฝั่ง Response
จัดการ response หลังได้รับจาก server:
// เพิ่ม response interceptor
const removeInterceptor = http.addResponseInterceptor(
// onFulfilled - จัดการ response ที่สำเร็จ
(response) => {
console.log('Response received:', response.status);
// แก้ไข response ถ้าต้องการ
response.receivedAt = Date.now();
return response;
},
// onRejected - จัดการ response ที่มีข้อผิดพลาด
(error) => {
console.error('Response error:', error);
// แก้ไข error หรือ throw ต่อ
if (error.status === 401) {
// เปลี่ยนเส้นทางไปหน้าเข้าสู่ระบบ
window.location.href = '/login';
}
throw error;
}
);
// ลบ interceptor
removeInterceptor();ตัวอย่างการใช้งาน Interceptor
1. เพิ่ม Authentication Token
http.addRequestInterceptor(config => {
const token = localStorage.getItem('auth_token');
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
return config;
});2. การบันทึก Log
// บันทึกคำขอ
http.addRequestInterceptor(config => {
console.log(`[${config.method}] ${config.url}`);
return config;
});
// บันทึกการตอบกลับ
http.addResponseInterceptor(
response => {
console.log(`[${response.status}] ${response.url}`);
return response;
},
error => {
console.error(`[Error] ${error.status} - ${error.message}`);
throw error;
}
);3. ลองใหม่เมื่อเกิดข้อผิดพลาดเครือข่าย
http.addResponseInterceptor(
response => response,
async (error) => {
if (error.status === 0 || error.status === 408) {
console.log('Network error, retrying...');
// ลองเรียกคำขอเดิมอีกครั้ง
return await http.request(error.url);
}
throw error;
}
);4. แปลงโครงสร้าง Response
http.addResponseInterceptor(response => {
// แปลง response format
return {
success: response.ok,
result: response.data,
errors: response.ok ? null : response.data?.errors,
timestamp: Date.now()
};
});5. จำกัดอัตราการเรียก (Rate Limiting)
const requestTimestamps = [];
http.addRequestInterceptor(config => {
const now = Date.now();
// ลบ timestamps ที่เก่ากว่า 1 นาที
const oneMinuteAgo = now - 60000;
while (requestTimestamps.length && requestTimestamps[0] < oneMinuteAgo) {
requestTimestamps.shift();
}
// ตรวจสอบ rate limit (max 60 requests/minute)
if (requestTimestamps.length >= 60) {
throw new Error('Rate limit exceeded. Please wait.');
}
requestTimestamps.push(now);
return config;
});การป้องกัน CSRF
HttpClient มี CSRF protection built-in เพื่อป้องกัน Cross-Site Request Forgery attacks
การเปิดใช้งาน CSRF
const client = new HttpClient({
security: {
csrf: {
enabled: true,
tokenName: '_token',
headerName: 'X-CSRF-Token'
}
}
});วิธีการทำงาน
CSRF token จะถูกดึงจาก:
- Meta tag (
<meta name="csrf-token" content="token-value">) - Cookie (ชื่อ
XSRF-TOKENโดย default)
<!-- ในส่วน <head> -->
<meta name="csrf-token" content="your-csrf-token-here">การแนบ CSRF Token อัตโนมัติ
Token จะถูกแนบอัตโนมัติใน:
- Header:
X-CSRF-Token: token-value - Request Body: สำหรับ POST/PUT/DELETE requests
// Token จะถูกแนบอัตโนมัติ
await client.post('/api/delete-item', { id: 123 });
// Request จะมี:
// Header: X-CSRF-Token: your-token
// Body: { id: 123, _token: 'your-token' }การตั้งค่า CSRF Token ด้วยตนเอง
// ตั้งค่า token ด้วยตนเอง
client.setCsrfToken('new-token-value');
// Token จะถูกใช้ใน requests ต่อไป
await client.post('/api/action', data);การต่ออายุ CSRF Token
HttpClient จะอัปเดต token อัตโนมัติจาก response header:
// เซิร์ฟเวอร์ส่ง header: X-CSRF-Token: new-token
const response = await client.post('/api/action', data);
// client.csrfToken จะถูกอัปเดตเป็น 'new-token' อัตโนมัติฟีเจอร์ด้านความปลอดภัย
HttpClient มีฟีเจอร์ด้านความปลอดภัยหลายอย่างที่สามารถเปิดใช้งานได้
1. การป้องกัน CSRF
ป้องกัน Cross-Site Request Forgery:
const client = new HttpClient({
security: {
csrf: {
enabled: true,
tokenName: '_token',
headerName: 'X-CSRF-Token'
}
}
});2. การจำกัดอัตราการเรียก (Rate Limiting)
จำกัดจำนวน requests (ต้องใช้งานร่วมกับ SecurityManager):
const client = new HttpClient({
security: {
rateLimit: {
enabled: true
}
}
});3. การตรวจสอบความถูกต้องของ Request
ทำความสะอาดข้อมูลใน request (ต้องใช้งานร่วมกับ SecurityManager):
const client = new HttpClient({
security: {
validation: {
enabled: true
}
}
});4. การตั้งค่า Timeout
ป้องกัน requests ที่ค้างนาน:
const client = new HttpClient({
timeout: 10000 // 10 วินาที
});
// หรือตั้งค่าทีหลัง
client.setTimeout(5000); // 5 วินาที5. การส่ง Credentials เฉพาะโดเมนเดียวกัน
ป้องกันการส่ง credentials ข้าม domain:
const client = new HttpClient();
// ค่าเริ่มต้น: credentials: 'same-origin'
await client.get('/api/data');
// ต้องการส่ง credentials ข้ามโดเมน
await client.get('https://api.example.com/data', {
credentials: 'include'
});การจัดการข้อผิดพลาด
HttpClient มีหลายวิธีในการจัดการ errors
1. โหมดปลอดภัย (อินสแตนซ์ http)
ใช้ http instance ที่ไม่ throw errors:
const response = await http.get('/api/users');
if (response.ok) {
console.log('Success:', response.data);
} else {
console.error('Error:', response.status, response.statusText);
// แสดง error message จาก server
if (response.data?.message) {
console.error('Server message:', response.data.message);
}
}2. โหมด Throw (อินสแตนซ์ httpThrow)
ใช้ httpThrow instance ที่ throw errors:
try {
const response = await httpThrow.get('/api/users');
console.log('Success:', response.data);
} catch (error) {
console.error('Error:', error.message);
console.error('Status:', error.status);
// จัดการ error ตาม status code
switch (error.status) {
case 401:
// เปลี่ยนเส้นทางไปหน้าเข้าสู่ระบบ
window.location.href = '/login';
break;
case 403:
alert('Access denied');
break;
case 404:
alert('Resource not found');
break;
case 422:
// ข้อมูลไม่ผ่านการตรวจสอบ
const errors = error.response.data.errors;
console.error('Validation errors:', errors);
break;
case 500:
alert('Server error. Please try again later.');
break;
default:
alert('An error occurred: ' + error.message);
}
}3. อินสแตนซ์แบบกำหนดเอง
สร้าง instance ที่มี error handling แบบกำหนดเอง:
const client = new HttpClient({
throwOnError: false // หรือ true ตามต้องการ
});
// กำหนดค่า throwOnError เฉพาะคำขอ
const response = await client.get('/api/users', {
throwOnError: true // ให้ throw error เฉพาะคำขอนี้
});4. Interceptor สำหรับจัดการข้อผิดพลาด
ใช้ response interceptor เพื่อจัดการ errors:
http.addResponseInterceptor(
response => response,
error => {
// บันทึกข้อผิดพลาด
console.error('API Error:', error);
// แสดงการแจ้งเตือน
if (window.NotificationManager) {
NotificationManager.error(error.message);
}
// เปลี่ยนเส้นทางเมื่อสิทธิ์หมดอายุ
if (error.status === 401) {
window.location.href = '/login';
return; // ไม่ต้องโยนข้อผิดพลาดต่อ
}
// โยนข้อผิดพลาดอื่นต่อ
throw error;
}
);5. ข้อผิดพลาดจาก Timeout
จัดการ timeout errors:
const response = await http.get('/api/slow-endpoint');
if (!response.ok && response.status === 408) {
console.error('Request timeout');
alert('The server is taking too long to respond. Please try again.');
}อ็อบเจ็กต์ HttpError
try {
await httpThrow.get('/api/users');
} catch (error) {
console.log(error.name); // 'HttpError'
console.log(error.message); // ข้อความข้อผิดพลาด
console.log(error.status); // รหัสสถานะ HTTP
console.log(error.response); // อ็อบเจ็กต์ response แบบเต็ม
console.log(error.timestamp); // เวลาที่เกิดข้อผิดพลาด
}ตัวอย่างการใช้งาน
1. การเรียก API แบบง่าย
// ใช้ simpleFetch
const users = await simpleFetch.json('/api/users');
console.log(users);
// ใช้ http
const response = await http.get('/api/users');
if (response.ok) {
console.log(response.data);
}2. การส่งข้อมูล JSON
// ตัวอย่างคำขอ POST
const response = await http.post('/api/users', {
name: 'John Doe',
email: 'john@example.com',
age: 30
});
if (response.ok) {
console.log('Created:', response.data);
}
// ตัวอย่างคำขอ PUT
const response = await http.put('/api/users/1', {
name: 'Jane Doe',
email: 'jane@example.com'
});
// ตัวอย่างคำขอ PATCH
const response = await http.patch('/api/users/1', {
status: 'active'
});3. การอัปโหลดไฟล์
// อัปโหลดไฟล์เดียว
const fileInput = document.querySelector('#file');
const file = fileInput.files[0];
const response = await http.upload('/api/upload', file);
if (response.ok) {
console.log('Uploaded:', response.data.url);
}
// อัปโหลดหลายไฟล์พร้อมกัน
const files = Array.from(fileInput.files);
const response = await http.upload('/api/upload', files);
// อัปโหลดพร้อมส่งข้อมูลเพิ่มเติม
const response = await http.upload('/api/upload', file, {
data: {
title: 'Profile Picture',
category: 'avatars'
}
});4. การใช้งาน FormData
const formData = new FormData();
formData.append('name', 'John Doe');
formData.append('email', 'john@example.com');
formData.append('avatar', file);
const response = await http.post('/api/users', formData);5. การดาวน์โหลดไฟล์
const response = await http.get('/api/reports/download', {
headers: {
'Accept': 'application/pdf'
}
});
if (response.ok) {
// response.data จะเป็น Blob
const blob = response.data;
// สร้างลิงก์สำหรับดาวน์โหลด
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'report.pdf';
a.click();
URL.revokeObjectURL(url);
}6. การใช้งาน Query Parameters
// สร้างพารามิเตอร์เอง
const response = await http.get('/api/users?page=1&limit=10&sort=name');
// ใช้ URLSearchParams
const params = new URLSearchParams({
page: 1,
limit: 10,
sort: 'name'
});
const response = await http.get(`/api/users?${params}`);7. การยกเลิก Request
const controller = new AbortController();
// เริ่มส่งคำขอ
const responsePromise = http.get('/api/large-data', {
signal: controller.signal
});
// ยกเลิกหลังผ่านไป 5 วินาที
setTimeout(() => {
controller.abort();
}, 5000);
try {
const response = await responsePromise;
console.log(response.data);
} catch (error) {
if (error.name === 'AbortError') {
console.log('ยกเลิกคำขอแล้ว');
}
}8. การใช้งาน Custom Headers
const response = await http.get('/api/data', {
headers: {
'X-Custom-Header': 'value',
'Accept-Language': 'th',
'X-App-Version': '1.0.0'
}
});9. การใช้งาน Authentication
// ตั้งค่า Bearer token
http.setDefaultHeader('Authorization', 'Bearer your-token-here');
// หรือใช้ interceptor เพื่อแนบ token อัตโนมัติ
http.addRequestInterceptor(config => {
const token = localStorage.getItem('auth_token');
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
return config;
});
// กำหนด Basic Auth
const username = 'user';
const password = 'pass';
const credentials = btoa(`${username}:${password}`);
http.setDefaultHeader('Authorization', `Basic ${credentials}`);10. การใช้งาน Base URL
// ตั้งค่า base URL
http.setBaseURL('https://api.example.com');
// ใช้งาน
await http.get('/users'); // เรียก https://api.example.com/users
await http.get('/posts'); // เรียก https://api.example.com/posts
// เรียก URL ภายนอกโดยไม่ใช้ base URL
await http.get('https://other-api.com/data'); // เรียก https://other-api.com/data11. Parallel Requests
// รอ requests ทั้งหมดเสร็จ
const [users, posts, comments] = await Promise.all([
http.get('/api/users'),
http.get('/api/posts'),
http.get('/api/comments')
]);
console.log('Users:', users.data);
console.log('Posts:', posts.data);
console.log('Comments:', comments.data);
// รอ request แรกที่เสร็จ
const response = await Promise.race([
http.get('/api/fast-endpoint'),
http.get('/api/slow-endpoint')
]);12. Retry Logic
async function fetchWithRetry(url, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await http.get(url);
if (response.ok) {
return response;
}
// ลองใหม่เมื่อเกิดข้อผิดพลาดฝั่งเซิร์ฟเวอร์
if (response.status >= 500 && i < maxRetries - 1) {
console.log(`Retry ${i + 1}/${maxRetries}...`);
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
continue;
}
return response;
}
}
const response = await fetchWithRetry('/api/unstable-endpoint');13. การติดตามความคืบหน้า (ขณะอัปโหลด)
// ใช้ XMLHttpRequest สำหรับ progress tracking
function uploadWithProgress(url, file, onProgress) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
const formData = new FormData();
formData.append('file', file);
xhr.upload.addEventListener('progress', (e) => {
if (e.lengthComputable) {
const percent = (e.loaded / e.total) * 100;
onProgress(percent);
}
});
xhr.addEventListener('load', () => {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(JSON.parse(xhr.responseText));
} else {
reject(new Error(xhr.statusText));
}
});
xhr.addEventListener('error', () => reject(new Error('Upload failed')));
xhr.open('POST', url);
xhr.send(formData);
});
}
// ใช้งาน
const file = document.querySelector('#file').files[0];
const result = await uploadWithProgress('/api/upload', file, (percent) => {
console.log(`กำลังอัปโหลด: ${percent.toFixed(2)}%`);
});เอกสารอ้างอิง API
คลาส HttpClient
คอนสตรักเตอร์
new HttpClient(options?: HttpClientOptions): HttpClientคุณสมบัติ
| คุณสมบัติ | ประเภท | คำอธิบาย |
|---|---|---|
baseURL |
string |
Base URL สำหรับทุก request |
defaultHeaders |
object |
Header เริ่มต้น |
timeout |
number |
เวลา timeout (มิลลิวินาที) |
throwOnError |
boolean |
ให้ throw error เมื่อสถานะไม่ใช่ 2xx |
csrfToken |
string \| null |
โทเคน CSRF |
interceptors |
object |
ตัวดัก request/response |
เมธอด
เมธอด HTTP
get(url: string, options?: RequestOptions): Promise<Response>
post(url: string, data?: any, options?: RequestOptions): Promise<Response>
put(url: string, data?: any, options?: RequestOptions): Promise<Response>
delete(url: string, options?: RequestOptions): Promise<Response>
patch(url: string, data?: any, options?: RequestOptions): Promise<Response>
head(url: string, options?: RequestOptions): Promise<Response>
options(url: string, options?: RequestOptions): Promise<Response>เมธอดโหมดปลอดภัย
getSafe(url: string, options?: RequestOptions): Promise<Response>
postSafe(url: string, data?: any, options?: RequestOptions): Promise<Response>
putSafe(url: string, data?: any, options?: RequestOptions): Promise<Response>
deleteSafe(url: string, options?: RequestOptions): Promise<Response>เมธอดอื่นๆ
upload(url: string, files: File | File[], options?: UploadOptions): Promise<Response>
request(url: string, options?: RequestOptions): Promise<Response>เมธอดปรับแต่งค่า
setBaseURL(url: string): void
setDefaultHeader(name: string, value: string): void
setDefaultHeaders(headers: object): void
setTimeout(timeout: number): void
setCsrfToken(token: string): voidเมธอดของ Interceptor
addRequestInterceptor(fn: (config) => config | Promise<config>): () => void
addResponseInterceptor(onFulfilled?: (response) => response, onRejected?: (error) => error): () => voidยูทิลิตี้ simpleFetch
เมธอด
// HTTP Methods
fetch(url: string, options?: RequestOptions): Promise<Response>
get(url: string, options?: RequestOptions): Promise<Response>
post(url: string, data?: any, options?: RequestOptions): Promise<Response>
put(url: string, data?: any, options?: RequestOptions): Promise<Response>
delete(url: string, options?: RequestOptions): Promise<Response>
patch(url: string, data?: any, options?: RequestOptions): Promise<Response>
// Convenience Methods
json(url: string, options?: RequestOptions): Promise<any>
text(url: string, options?: RequestOptions): Promise<string>
postJson(url: string, data: any, options?: RequestOptions): Promise<any>
// Upload Method
upload(url: string, files: File | File[] | FormData, data?: object, options?: RequestOptions): Promise<Response>
// Configuration Methods
setBaseURL(url: string): simpleFetch
setHeaders(headers: object): simpleFetch
setHeader(name: string, value: string): simpleFetch
setTimeout(timeout: number): simpleFetch
removeHeader(name: string): simpleFetch
resetConfig(): simpleFetchแนวปฏิบัติที่ดีที่สุด
1. ✅ เลือกใช้ Export ที่เหมาะสม
// ❌ ไม่ดี: ใช้ HttpClient class เมื่อไม่จำเป็น
const client = new HttpClient();
const response = await client.get('/api/users');
// ✅ ดี: ใช้ simpleFetch หรือ http instance
const users = await simpleFetch.json('/api/users');
// หรือ
const response = await http.get('/api/users');2. ✅ ตั้งค่า Base URL
// ❌ ไม่ดี: URL เต็มทุกครั้ง
await http.get('https://api.example.com/users');
await http.get('https://api.example.com/posts');
// ✅ ดี: ตั้งค่า base URL
http.setBaseURL('https://api.example.com');
await http.get('/users');
await http.get('/posts');3. ✅ ใช้ Interceptors สำหรับ Common Tasks
// ❌ ไม่ดี: เพิ่ม token ทุกครั้ง
const token = localStorage.getItem('token');
await http.get('/api/users', {
headers: { 'Authorization': `Bearer ${token}` }
});
// ✅ ดี: ใช้ interceptor
http.addRequestInterceptor(config => {
const token = localStorage.getItem('token');
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
return config;
});
await http.get('/api/users');4. ✅ จัดการ Errors อย่างเหมาะสม
// ❌ ไม่ดี: ไม่ตรวจสอบ response
const response = await http.get('/api/users');
console.log(response.data); // อาจเป็น null
// ✅ ดี: ตรวจสอบ response.ok
const response = await http.get('/api/users');
if (response.ok) {
console.log(response.data);
} else {
console.error('ข้อผิดพลาด:', response.statusText);
}
// ✅ ดีกว่า: ใช้ httpThrow
try {
const response = await httpThrow.get('/api/users');
console.log(response.data);
} catch (error) {
console.error('ข้อผิดพลาด:', error.message);
}5. ✅ ใช้ AbortController สำหรับ Long Requests
// ✅ ดี: สามารถยกเลิกได้
const controller = new AbortController();
button.addEventListener('click', () => {
http.get('/api/large-data', {
signal: controller.signal
});
});
cancelButton.addEventListener('click', () => {
controller.abort();
});6. ✅ ระบุ Content-Type ที่ถูกต้อง
// ❌ ไม่ดี: ระบุ Content-Type สำหรับ FormData
await http.post('/api/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' }
});
// ✅ ดี: ปล่อยให้ browser ตั้งค่าเอง
await http.post('/api/upload', formData);7. ✅ เปิดใช้งาน CSRF Protection
// ✅ ดี: เปิดใช้งาน CSRF protection
const client = new HttpClient({
security: {
csrf: {
enabled: true,
headerName: 'X-CSRF-Token'
}
}
});8. ✅ ตั้งค่า Timeout ที่เหมาะสม
// ❌ ไม่ดี: Timeout เดียวกันทุก request
http.setTimeout(5000);
// ✅ ดี: Timeout ต่างกันตาม request type
http.setTimeout(30000); // Default
await http.get('/api/quick', { timeout: 5000 });
await http.post('/api/process', data, { timeout: 120000 });9. ✅ Cleanup Interceptors
// ❌ ไม่ดี: ไม่ cleanup
http.addRequestInterceptor(config => {
// ...
return config;
});
// ✅ ดี: เก็บ remove function
const removeInterceptor = http.addRequestInterceptor(config => {
// ...
return config;
});
// Cleanup เมื่อไม่ต้องการแล้ว
removeInterceptor();10. ✅ Handle Network Errors
const response = await http.get('/api/users');
if (!response.ok) {
if (response.status === 0 || response.status === 408) {
// ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ได้
alert('Cannot connect to server');
} else if (response.status >= 500) {
// เซิร์ฟเวอร์มีปัญหา
alert('Server error. Please try again later.');
} else {
// เกิดข้อผิดพลาด
alert('An error occurred: ' + response.statusText);
}
}สรุป
เลือกใช้ Export ที่เหมาะสม
| ถ้าคุณต้องการ... | ใช้... |
|---|---|
| ความเรียบง่าย, เบา | simpleFetch |
| Safe mode (ไม่ throw error) | http |
| Throw errors อัตโนมัติ | httpThrow |
| Custom configuration | new HttpClient() |
ฟีเจอร์หลัก
| ฟีเจอร์ | HttpClient | http | httpThrow | simpleFetch |
|---|---|---|---|---|
| Interceptors | ✅ | ✅ | ✅ | ❌ |
| CSRF Protection | ✅ | ✅ | ✅ | ❌ |
| Throw on Error | ตามที่กำหนด | ❌ | ✅ | ❌ |
| Custom Handler | ✅ | ✅ | ✅ | ❌ |
| Auto Bearer Token | ❌ | ❌ | ❌ | ✅ |
| Convenience Methods | ❌ | ❌ | ❌ | ✅ |