【问题解决】Error 400. The request has an invalid header name

本文记录了解决访问微软必应词典接口时遇到的HTTP 400错误过程,错误源于请求头中User-Agent字段被不当处理,通过调整读取请求头文件的方法解决了问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在爬虫的过程中,访问微软必应词典接口时,遇到了Error 400. The request has an invalid header name的错误。
请求头文件如下:

Host: cn.bing.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache
TE: Trailers

构建http请求头:

static Header[] getHeader(String headersPath) {
		//fileToLines :工具类,把文件以行字符串为单位,读到一个list中
		ArrayList<String> hs=FileUtils.fileToLines(new File(headersPath));
		//org.apache.http.Header;
		Header[] headers=new Header[hs.size()];
		for (int i=0;i<headers.length;i++) {
			String key=hs.get(i).split(":",2)[0];
			String value=hs.get(i).split(":",2)[1];
			headers[i]=new BasicHeader(key, value);
		}
		return headers;
	}

发送请求:

public void doGet()throws Exception{
	CloseableHttpClient httpClient = HttpClients.createDefault();
        String url = "https://cn.bing.com/dict/search?q=happily";
        //Get方法
        HttpGet httpGet = new HttpGet(url);
        //配置各种响应时间
        RequestConfig requestConfig = RequestConfig.custom()  
                .setConnectTimeout(3000).setConnectionRequestTimeout(1000)  
                .setSocketTimeout(5000).build();  
        httpGet.setConfig(requestConfig); 
		//调用上面getHeader方法
        httpGet.setHeaders(getHeader("D:\\desktop\\新建文本文档.txt"));
        //执行请求
		CloseableHttpResponse httpResponse=httpClient.execute(httpGet);
		int statusCode = httpResponse.getStatusLine().getStatusCode();//状态码
		System.out.println(statusCode);
		//获取响应内容
		String content= EntityUtils.toString(httpResponse.getEntity(), "utf-8");
		System.out.println(content);
}

执行结果如下:

400
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request - Invalid Header</h2>
<hr><p>HTTP Error 400. The request has an invalid header name.</p>
</BODY></HTML>

提示请求包含不合法请求头。
我寻思着请求头都合法啊,还又挨个去看了D:\desktop\新建文本文档.txt,我文件里面的请求头。
然后就想,是不是把请求头读到list中的fileToLines方法出问题了,导致设置的请求头和文件里的请求头不一样

查看fileToLines方法:

public static Collection<String> fileToLines(String fileName,Collection<String>list){
		try (BufferedReader br=new BufferedReader(new FileReader(fileName))){
			String info;
			while((info=br.readLine())!=null) {
				list.add(info.replaceAll("\\s*", ""));
			}
		} catch (Exception e) {
		}
		return list;
	}

看到方法的那一刻,我立马明白了!replaceAll("\s", “”)把所有空格换行什么的,都整没了!
导致请求头中的:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0
变成了:
User-Agent:Mozilla/5.0(WindowsNT10.0;Win64;x64;rv:69.0)Gecko/20100101Firefox/69.0
所有空格都没了,这不是合法的UA。
想必是以前出于某种需求,改了工具类的fileToLines方法。
教训:莫要在抽象出来的工具类中添加特定需求代码!如:replaceAll("\s", “”)

至此问题解决!

### 解决 Tomcat HTTP 400 错误:请求主机名无效 当遇到 Tomcat 中的 HTTP 400 错误并提示“请求主机名无效”时,通常是因为客户端发送了一个不被服务器认可的 Host 头部字段。以下是可能的原因以及解决方案: #### 可能原因分析 1. **Host 配置问题**: 如果 `server.xml` 文件中的 `<Connector>` 元素配置了 `allowedHosts` 属性,则只有指定的主机名会被接受[^1]。 2. **虚拟主机设置不当**: 当使用 `<Host>` 定义多个虚拟主机时,如果请求的主机名未匹配到任何已定义的虚拟主机,可能会返回此错误[^2]。 #### 解决方案 ##### 方法一:检查 Connector 的 allowedHosts 设置 在 Tomcat 的 `conf/server.xml` 文件中,找到 `<Connector>` 节点。默认情况下,该属性可能是空的或者设置了特定的允许列表。如果没有特别需求,可以移除或清空 `allowedHosts` 属性以接受所有主机名: ```xml <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" allowedHosts="" /> ``` 如果确实需要限制某些主机名访问,应确保目标主机名已被正确列入白名单。 ##### 方法二:验证 Virtual Host 配置 确认是否存在与请求主机名相匹配的 `<Host>` 条目。例如,在 `server.xml` 中添加如下条目来支持额外域名: ```xml <Host name="example.com" appBase="webapps"> <Context path="" docBase="myapp"/> </Host> ``` 对于未知主机名的情况,默认会映射至第一个定义的 `<Host>` 下的内容。因此建议保留一个通用的默认主机作为兜底处理。 ##### 方法三:调整日志级别排查具体异常 通过修改 logging.properties 或 logback.xml 增加详细的调试信息可以帮助定位确切失败位置。例如启用更细粒度的日志记录以便观察实际接收到的 Host Header 是否符合预期[^3]: ```properties org.apache.coyote.http11.Http11Processor.level = FINEST ``` 完成上述更改之后重启服务使改动生效,并重新测试触发条件看是否解决问题。 ```bash ./bin/shutdown.sh && ./bin/startup.sh ``` 最后再次尝试发起原始请求路径看看能否正常工作。 --- ###
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值