跳到主要内容

JavaScript 请求头

在网络通信中,HTTP请求头(Headers)承载着客户端和服务器之间交换的元数据信息,是网络请求中不可或缺的组成部分。本文将帮助你全面了解JavaScript中如何处理请求头,以及它们在实际开发中的重要应用。

什么是请求头?

HTTP请求头是客户端发送到服务器的请求中包含的一系列键值对,用于传递有关请求或客户端本身的附加信息。

请求头携带了诸如浏览器类型、认证信息、内容类型等元数据,帮助服务器正确处理请求。

常见的HTTP请求头

在开始学习如何操作请求头之前,让我们先了解一些常见的请求头:

  • Content-Type: 指定请求体的媒体类型
  • Authorization: 包含用于验证用户身份的凭证
  • User-Agent: 标识发起请求的客户端应用程序
  • Accept: 指定客户端能够接受的内容类型
  • Accept-Language: 指定客户端首选的语言
  • Cookie: 包含先前由服务器设置的HTTP cookie
  • Cache-Control: 指定请求和响应中的缓存机制

使用XMLHttpRequest设置请求头

使用传统的XMLHttpRequest对象,你可以通过setRequestHeader()方法设置请求头:

javascript
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true);

// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Bearer your-token-here');

xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
}
};

xhr.send();
注意

setRequestHeader() 方法必须在 open() 之后、send() 之前调用,否则会抛出错误。

使用Fetch API处理请求头

现代JavaScript应用更多地使用Fetch API来处理网络请求。使用Fetch设置请求头非常直观:

javascript
fetch('https://api.example.com/data', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer your-token-here',
'X-Custom-Header': 'Custom Value'
}
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

使用Headers对象

Fetch API提供了一个专门的Headers对象,使请求头的操作更加灵活:

javascript
// 创建一个新的Headers对象
const headers = new Headers();

// 添加头信息
headers.append('Content-Type', 'application/json');
headers.append('Authorization', 'Bearer your-token-here');

// 检查、获取和设置头信息
if (headers.has('Content-Type')) {
console.log(headers.get('Content-Type')); // 输出: application/json
}

// 使用headers对象发起请求
fetch('https://api.example.com/data', {
method: 'GET',
headers: headers
})
.then(response => response.json())
.then(data => console.log(data));

Headers对象提供了以下方法:

  • append(): 添加一个新的键值对
  • delete(): 删除指定的头信息
  • get(): 获取指定头信息的值
  • has(): 检查是否存在指定的头信息
  • set(): 设置或替换指定的头信息

使用Axios处理请求头

Axios是一个流行的HTTP客户端库,它提供了一个简洁的API来处理请求头:

javascript
// 全局默认请求头
axios.defaults.headers.common['Authorization'] = 'Bearer your-token-here';
axios.defaults.headers.post['Content-Type'] = 'application/json';

// 特定请求的头信息
axios.get('https://api.example.com/data', {
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Accept-Language': 'zh-CN'
}
})
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error('Error:', error);
});

常见应用场景

1. 内容协商

通过请求头告诉服务器客户端首选的数据格式:

javascript
fetch('https://api.example.com/data', {
headers: {
'Accept': 'application/json',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8'
}
})
.then(response => response.json())
.then(data => console.log(data));

2. 认证和授权

通过请求头传递身份验证信息:

javascript
fetch('https://api.example.com/protected-data', {
headers: {
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
}
})
.then(response => {
if (!response.ok) {
throw new Error('Authentication failed');
}
return response.json();
})
.then(data => console.log(data));

3. 缓存控制

使用请求头控制缓存行为:

javascript
fetch('https://api.example.com/data', {
headers: {
'Cache-Control': 'no-cache',
'Pragma': 'no-cache'
}
})
.then(response => response.json())
.then(data => console.log(data));

4. 跨域资源共享(CORS)

当你需要发送凭证到启用了CORS的不同域时:

javascript
fetch('https://api.different-domain.com/data', {
credentials: 'include', // 包含凭证
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => response.json())
.then(data => console.log(data));

5. 自定义请求头

有时候API需要特定的自定义请求头:

javascript
fetch('https://api.example.com/data', {
headers: {
'X-API-Key': 'your-api-key',
'X-Client-ID': 'your-client-id'
}
})
.then(response => response.json())
.then(data => console.log(data));
备注

自定义请求头通常以X-前缀开头,不过这只是一种惯例,而非规范要求。

实际案例:构建一个带请求头的天气API查询应用

下面是一个使用请求头访问天气API的简单示例:

javascript
// 天气API查询函数
async function getWeather(city) {
try {
const response = await fetch(`https://api.weatherapi.com/v1/current.json?q=${city}`, {
method: 'GET',
headers: {
'X-API-Key': 'your-api-key-here',
'Accept': 'application/json',
'Accept-Language': 'zh-CN'
}
});

if (!response.ok) {
throw new Error(`Weather API error: ${response.status}`);
}

const data = await response.json();
return data;
} catch (error) {
console.error('Failed to fetch weather data:', error);
throw error;
}
}

// 使用该函数
document.getElementById('weatherButton').addEventListener('click', async () => {
const city = document.getElementById('cityInput').value;
try {
const weatherData = await getWeather(city);
displayWeather(weatherData);
} catch (error) {
showError(error.message);
}
});

// 显示天气信息
function displayWeather(data) {
const weatherDiv = document.getElementById('weatherResult');
weatherDiv.innerHTML = `
<h3>当前天气: ${data.location.name}</h3>
<p>温度: ${data.current.temp_c}°C</p>
<p>天气状况: ${data.current.condition.text}</p>
<p>风速: ${data.current.wind_kph} km/h</p>
`;
}

// 显示错误
function showError(message) {
const weatherDiv = document.getElementById('weatherResult');
weatherDiv.innerHTML = `<p class="error">错误: ${message}</p>`;
}

对应的HTML:

html
<div class="weather-app">
<h2>天气查询</h2>
<div class="input-group">
<input type="text" id="cityInput" placeholder="输入城市名称" />
<button id="weatherButton">查询天气</button>
</div>
<div id="weatherResult"></div>
</div>

获取响应头

除了设置请求头,有时我们也需要获取服务器的响应头信息:

使用XMLHttpRequest获取响应头

javascript
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
// 获取所有响应头
const allHeaders = xhr.getAllResponseHeaders();
console.log(allHeaders);

// 获取特定响应头
const contentType = xhr.getResponseHeader('Content-Type');
console.log('Content-Type:', contentType);
}
};
xhr.send();

使用Fetch API获取响应头

javascript
fetch('https://api.example.com/data')
.then(response => {
// 获取特定响应头
console.log('Content-Type:', response.headers.get('Content-Type'));

// 遍历所有响应头
response.headers.forEach((value, name) => {
console.log(`${name}: ${value}`);
});

return response.json();
})
.then(data => console.log(data));

请求头相关的安全考虑

在处理请求头时,需要注意一些安全方面的考虑:

  1. 敏感信息: 避免在请求头中包含敏感信息,除非使用HTTPS加密传输。
  2. CORS限制: 浏览器对某些请求头有严格的CORS限制,如AuthorizationCookie等。
  3. 预检请求: 含有自定义请求头的跨域请求可能触发预检请求(OPTIONS)。
注意

永远不要在请求头中明文传输密码或API密钥,除非使用HTTPS连接。即使如此,最佳实践是使用适当的认证机制(如OAuth)而不是原始凭证。

总结

请求头是HTTP通信的关键组成部分,掌握如何在JavaScript中设置和使用请求头对于开发现代Web应用至关重要。通过本文,我们学习了:

  • 请求头的基本概念和常见请求头
  • 使用不同技术(XMLHttpRequest, Fetch API, Axios)设置请求头
  • 实际应用场景和具体示例
  • 获取响应头的方法
  • 处理请求头时的安全注意事项

通过合理使用请求头,你可以更好地控制客户端与服务器之间的通信,实现更复杂的交互需求。

练习

  1. 创建一个函数,使用Fetch API发送带有认证信息的请求。
  2. 实现一个简单的缓存控制机制,使用请求头确保每次请求都获取最新数据。
  3. 创建一个小应用,使用自定义请求头与API通信,并处理可能的CORS问题。

推荐资源

通过这些练习和资源,你将能够更熟练地在JavaScript应用中使用请求头,提升你的网络请求处理能力。