Java HttpURLConnection setRequestProperty 未设置自定义 header 密钥
Java HttpURLConnection setRequestProperty is not setting custom header key
我想发送一个自定义的 http header 请求并且我这样设置自定义键:
con.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
con.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
con.setRequestProperty("Accept-Language", "ro-RO,ro;q=0.9,en-US;q=0.8,en;q=0.7");
con.setRequestProperty("Cache-Control", "max-age=0");
con.setRequestProperty("sec-ch-ua", "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"90\", \"Google Chrome\";v="90"");
con.setRequestProperty("sec-ch-ua-mobile", "?0");
con.setRequestProperty("Sec-Fetch-Dest", "document");
con.setRequestProperty("Sec-Fetch-Mode", "navigate");
con.setRequestProperty("Sec-Fetch-Site", "none");
con.setRequestProperty("Sec-Fetch-User", "?1");
con.setRequestProperty("Upgrade-Insecure-Requests", "1");
con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36");
问题是所有以“sec”或“Sec”开头的属性都没有正确设置。
我在使用 setRequestProperty 设置它们后立即使用方法 getRequestProperty 对其进行了测试。
我还通过使用 fiddler 拦截 https 流量进行了测试。
我也尝试使用 addRequestProperty 方法而不是 setRequestProperty 来设置请求 属性,但结果是一样的。
为什么 Java 不接受某些属性?
更新
简单示例:
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
public class SetRequestProperty_example {
public static void main(String[] args) {
try {
URL url = new URL("http://xyz.abc");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestProperty("Sec-Fetch-Dest", "document");
//con.addRequestProperty("Sec-Fetch-Dest", "document"); //same problem appears with addRequestProperty
String check = con.getRequestProperty("Sec-Fetch-Dest");
if(check==null) {
System.err.println("Problem detected");
} else {
System.err.println("Problem solved");
}
} catch (IOException ex) {
Logger.getLogger(SetRequestProperty_example.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
这个简单的代码显示“检测到问题”,我应该写什么来显示“问题已解决”?
更新
这很奇怪,但是如果我将请求 属性 的名称从“Sec-Fetch-Dest”更改为“SSec-Fetch-Dest”,那么 属性 就设置好了。这并没有解决问题,但我认为它可能是一个有用的信息。
根据 mozilla 文档,header以“Sec”开头的是禁止列表的一部分,因此“理论上”不能以编程方式修改它们。
A forbidden header name is the name of any HTTP header that cannot be modified programmatically; specifically, an HTTP request header name (in contrast with a Forbidden response header name).
Modifying such headers is forbidden because the user agent retains full control over them. Names starting with Sec-
are reserved for creating new headers safe from APIs using Fetch that grant developers control over headers, such as XMLHttpRequest.
Source: https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name
因此,当您尝试调用“setRequestProperty”方法时,未存储 header。
如果您使用的是 Java 11 或更高版本,您也可以尝试使用 HttpClient,我测试了代码并且它在运行时正确存储了 header,这是一个示例:
HttpClient httpClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_1_1)
.connectTimeout(Duration.ofSeconds(10))
.build();
HttpRequest request = HttpRequest.newBuilder(
URI.create("http://xyz.abc"))
.header("Sec-Fetch-Dest", "document")
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
// print status code
System.out.println(response.statusCode());
// print response body
System.out.println(response.body());
我想发送一个自定义的 http header 请求并且我这样设置自定义键:
con.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
con.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
con.setRequestProperty("Accept-Language", "ro-RO,ro;q=0.9,en-US;q=0.8,en;q=0.7");
con.setRequestProperty("Cache-Control", "max-age=0");
con.setRequestProperty("sec-ch-ua", "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"90\", \"Google Chrome\";v="90"");
con.setRequestProperty("sec-ch-ua-mobile", "?0");
con.setRequestProperty("Sec-Fetch-Dest", "document");
con.setRequestProperty("Sec-Fetch-Mode", "navigate");
con.setRequestProperty("Sec-Fetch-Site", "none");
con.setRequestProperty("Sec-Fetch-User", "?1");
con.setRequestProperty("Upgrade-Insecure-Requests", "1");
con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36");
问题是所有以“sec”或“Sec”开头的属性都没有正确设置。
我在使用 setRequestProperty 设置它们后立即使用方法 getRequestProperty 对其进行了测试。
我还通过使用 fiddler 拦截 https 流量进行了测试。
我也尝试使用 addRequestProperty 方法而不是 setRequestProperty 来设置请求 属性,但结果是一样的。
为什么 Java 不接受某些属性?
更新
简单示例:
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
public class SetRequestProperty_example {
public static void main(String[] args) {
try {
URL url = new URL("http://xyz.abc");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestProperty("Sec-Fetch-Dest", "document");
//con.addRequestProperty("Sec-Fetch-Dest", "document"); //same problem appears with addRequestProperty
String check = con.getRequestProperty("Sec-Fetch-Dest");
if(check==null) {
System.err.println("Problem detected");
} else {
System.err.println("Problem solved");
}
} catch (IOException ex) {
Logger.getLogger(SetRequestProperty_example.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
这个简单的代码显示“检测到问题”,我应该写什么来显示“问题已解决”?
更新 这很奇怪,但是如果我将请求 属性 的名称从“Sec-Fetch-Dest”更改为“SSec-Fetch-Dest”,那么 属性 就设置好了。这并没有解决问题,但我认为它可能是一个有用的信息。
根据 mozilla 文档,header以“Sec”开头的是禁止列表的一部分,因此“理论上”不能以编程方式修改它们。
A forbidden header name is the name of any HTTP header that cannot be modified programmatically; specifically, an HTTP request header name (in contrast with a Forbidden response header name).
Modifying such headers is forbidden because the user agent retains full control over them. Names starting with
Sec-
are reserved for creating new headers safe from APIs using Fetch that grant developers control over headers, such as XMLHttpRequest. Source: https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name
因此,当您尝试调用“setRequestProperty”方法时,未存储 header。
如果您使用的是 Java 11 或更高版本,您也可以尝试使用 HttpClient,我测试了代码并且它在运行时正确存储了 header,这是一个示例:
HttpClient httpClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_1_1)
.connectTimeout(Duration.ofSeconds(10))
.build();
HttpRequest request = HttpRequest.newBuilder(
URI.create("http://xyz.abc"))
.header("Sec-Fetch-Dest", "document")
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
// print status code
System.out.println(response.statusCode());
// print response body
System.out.println(response.body());