Properly Setting Headers in API Requests
A common oversight when making API requests is forgetting to set necessary headers, which can lead to failed requests, CORS errors, or servers rejecting your requests.
The Problem: Missing Headers
// ❌ Common mistake - no headers specified
fetch('/api/data')
.then(response => response.json())
.then(data => console.log(data));
Why Headers Matter
- Authentication: Bearer tokens, API keys
- Content Type: Specifying request format (JSON, form data)
- CORS: Required for cross-origin requests
- Server Expectations: APIs often require specific headers
Correct Implementation
1. Basic Headers with Fetch
fetch('/api/data', {
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer your-token-here'
}
})
.then(response => response.json())
.then(data => console.log(data));
2. With Async/Await
async function fetchData() {
const response = await fetch('/api/data', {
headers: {
'Accept': 'application/json',
'Authorization': `Bearer ${localStorage.getItem('token')}`
}
});
return await response.json();
}
3. Common Headers to Include
Header | Purpose | Example Value |
---|---|---|
Content-Type | Request body format | application/json |
Accept | Response format | application/json |
Authorization | Authentication | Bearer eyJhbGciOi... |
X-Requested-With | Identify AJAX | XMLHttpRequest |
Best Practices
- Create a Headers Utility:
// headers.js
export function getAuthHeaders() {
return {
'Content-Type': 'application/json',
'Authorization': `Bearer ${getToken()}`,
'Accept': 'application/json'
};
}
// Usage
fetch('/api/data', {
headers: getAuthHeaders()
});
- Use Interceptors (Axios):
// Configure once
axios.interceptors.request.use(config => {
config.headers.Authorization = `Bearer ${getToken()}`;
config.headers['Content-Type'] = 'application/json';
return config;
});
- Handle Content Types Properly:
// For JSON
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
// For FormData - let browser set headers
const formData = new FormData();
fetch('/api/upload', {
method: 'POST',
body: formData
// No Content-Type header - browser sets it automatically
})
Common Pitfalls
- Forgetting Content-Type:
// ❌ Server won't know how to parse
fetch('/api', {
method: 'POST',
body: JSON.stringify(data) // Missing Content-Type
});
- Incorrect Authorization:
headers: {
'Authorization': 'Bearer' // ❌ Missing token
}
- Case Sensitivity:
headers: {
'content-type': 'application/json' // ❌ Some servers expect 'Content-Type'
}
- CORS Issues:
// ❌ Missing CORS headers for cross-origin
fetch('https://other-domain.com/api')
Advanced Patterns
1. Dynamic Headers
function getHeaders(contentType = 'application/json') {
const headers = {
'Accept': 'application/json'
};
if (contentType) {
headers['Content-Type'] = contentType;
}
const token = getToken();
if (token) {
headers.Authorization = `Bearer ${token}`;
}
return headers;
}
2. Fetch Wrapper
async function apiRequest(url, method = 'GET', body = null) {
const options = {
method,
headers: getAuthHeaders(),
};
if (body) {
options.body = JSON.stringify(body);
}
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(await response.text());
}
return await response.json();
}
3. Using Axios Defaults
// Configure once
axios.defaults.headers.common['Authorization'] = `Bearer ${getToken()}`;
axios.defaults.headers.post['Content-Type'] = 'application/json';
// All requests will now include these headers
Key Takeaways
- Always set
Content-Type
when sending data - Include auth headers for protected endpoints
- Use interceptors to DRY up header configuration
- Consider CORS requirements for cross-origin requests
- Create utility functions for common header patterns
Remember: Proper headers are essential for successful API communication. They tell the server how to interpret your request and often include critical authentication information. Always verify your API documentation for required headers.