← Назад к вопросам
Как реализовать запрос через fetch без библиотек?
2.0 Middle🔥 111 комментариев
#JavaScript Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Реализация HTTP запросов через fetch API
Fetch API — это встроенный в браузер способ делать HTTP запросы без каких-либо библиотек. Это стандартное решение для современного JavaScript.
Базовый GET запрос
fetch('https://api.example.com/users')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error))
POST запрос с данными
fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token'
},
body: JSON.stringify({ name: 'John', email: 'john@example.com' })
})
.then(response => response.json())
.then(data => console.log('Created:', data))
.catch(error => console.error('Error:', error))
Обработка ошибок и статус кодов
async function fetchData(url) {
try {
const response = await fetch(url)
if (!response.ok) {
throw new Error(`HTTP Error: ${response.status}`)
}
const data = await response.json()
return data
} catch (error) {
console.error('Fetch failed:', error)
throw error
}
}
Реализация timeout через Promise.race
function fetchWithTimeout(url, timeoutMs = 5000) {
return Promise.race([
fetch(url),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout')), timeoutMs)
)
])
}
AbortController для отмены запросов
const controller = new AbortController()
const timeoutId = setTimeout(() => controller.abort(), 5000)
fetch('https://api.example.com/data', {
signal: controller.signal
})
.then(r => r.json())
.catch(error => {
if (error.name === 'AbortError') {
console.log('Request was cancelled')
}
})
.finally(() => clearTimeout(timeoutId))
Загрузка файла
const formData = new FormData()
formData.append('file', fileInput.files[0])
formData.append('name', 'My File')
fetch('/api/upload', {
method: 'POST',
body: formData
})
.then(r => r.json())
Параллельные запросы
Promise.all([
fetch('/api/users').then(r => r.json()),
fetch('/api/posts').then(r => r.json())
])
.then(([users, posts]) => {
console.log('All loaded:', { users, posts })
})
Promise.allSettled([
fetch('/api/users').then(r => r.json()),
fetch('/api/slow').then(r => r.json())
])
.then(results => {
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`Request ${index} succeeded:`, result.value)
} else {
console.log(`Request ${index} failed:`, result.reason)
}
})
})
Полезная wrapper функция
class API {
static async request(url, options = {}) {
const { method = 'GET', body, headers = {}, timeout = 10000 } = options
const controller = new AbortController()
const timeoutId = setTimeout(() => controller.abort(), timeout)
try {
const response = await fetch(url, {
method,
headers: { 'Content-Type': 'application/json', ...headers },
body: body ? JSON.stringify(body) : undefined,
signal: controller.signal
})
if (!response.ok) throw new Error(`HTTP ${response.status}`)
return response.json()
} catch (error) {
if (error.name === 'AbortError') throw new Error('Request timeout')
throw error
} finally {
clearTimeout(timeoutId)
}
}
static get(url) { return this.request(url, { method: 'GET' }) }
static post(url, body) { return this.request(url, { method: 'POST', body }) }
static put(url, body) { return this.request(url, { method: 'PUT', body }) }
static delete(url) { return this.request(url, { method: 'DELETE' }) }
}
API.get('/api/users').then(users => console.log(users))
API.post('/api/users', { name: 'John' }).then(user => console.log(user))
Преимущества и ограничения
Преимущества:
- Встроен в браузер, не нужны зависимости
- Promise-based синтаксис
- Современный стандартный подход
- Поддерживается везде кроме IE 11
Ограничения:
- Нет встроенного timeout (нужен AbortController)
- Нет встроенного retry (нужно писать самому)
- CORS требует правильной настройки
- Нет автоматического преобразования данных
Для production часто пишут wrapper над Fetch или используют axios.