在C#(Xamarin)中使用HttpRequestMessage发送指定名称自定义Header的问题
C#发送自定义Header后PHP端名称变化的原因及解决办法
嘿,我来帮你理清这个问题——其实这锅真的不是C#的HttpClient背的,是PHP对HTTP请求头的解析规则在搞事情!
先回顾下你的场景
你用C#写了一段发送POST请求的代码,自定义了SN-Authentication和SN-Date两个请求头:
client = new HttpClient(); client.MaxResponseContentBufferSize = 256000; int _TimeoutSec = 90; client.Timeout = new TimeSpan(0, 0, _TimeoutSec); string _ContentType = "application/json"; client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(_ContentType)); var uri = new Uri(String.Format(preparedAddress)); System.Net.Http.HttpRequestMessage msgToSend = new HttpRequestMessage(HttpMethod.Post, uri); // 自定义Header msgToSend.Headers.Add("SN-Authentication", AuthenticationLine); msgToSend.Headers.Add("SN-Date", dateValue); var content = new StringContent(json, Encoding.UTF8, "application/json"); content.Headers.ContentType = new MediaTypeHeaderValue(_ContentType); msgToSend.Content = content; HttpResponseMessage response; response = client.SendAsync(msgToSend).Result; String execResult = response.ReasonPhrase;
但PHP端收到的Header却是这样的:
Array ( [HTTP_SN_AUTHENTICATION] => Array ( [0] => my data 1 ) [HTTP_SN_DATE] => Array ( [0] => my data 2 ) )
你疑惑为什么C#会修改Header名称,其实真相是:
原因分析:这是PHP的标准化处理,不是C#的问题
HttpClient完全按照你写的原始名称发送了Header,你可以用抓包工具(比如Fiddler)验证——实际请求里的Header就是SN-Authentication和SN-Date。
而PHP会自动把HTTP请求头转换成$_SERVER数组的键,转换规则是:
- 把Header名称里的连字符
-替换成下划线_ - 所有字母转成大写
- 前面加上
HTTP_前缀
所以SN-Authentication就变成了HTTP_SN_AUTHENTICATION,这是PHP为了统一格式做的处理,和C#无关。
解决办法:在PHP端获取原始Header名称
如果你想拿到原始的Header名称,有两种靠谱的方式:
1. 使用getallheaders()函数(推荐)
这个函数会直接返回原始的请求头名称和对应值,在Apache或者PHP-FPM环境下都能正常使用:
$headers = getallheaders(); $authValue = $headers['SN-Authentication']; $dateValue = $headers['SN-Date'];
2. 遍历$_SERVER还原原始Header(兼容所有环境)
如果getallheaders()不可用(比如某些CGI模式),可以自己遍历$_SERVER数组来还原:
$originalHeaders = []; foreach ($_SERVER as $key => $value) { if (str_starts_with($key, 'HTTP_')) { // 去掉HTTP_前缀,把下划线换回连字符 $originalKey = str_replace('_', '-', substr($key, 5)); $originalHeaders[$originalKey] = $value; } } // 现在$originalHeaders里就有你要的原始Header了 $authValue = $originalHeaders['SN-Authentication'];
总结一下:C#并没有修改你的Header名称,是PHP的解析规则导致了名称变化,用上面的方法就能在PHP端拿到原始的Header啦!
内容的提问来源于stack exchange,提问作者Ivan P.
相关产品推荐
相关产品推荐

