将JavaScript GET请求转为PHP Curl后出现401错误求助
解决PHP CURL请求401未授权的问题
嘿,我一眼就瞅出问题所在啦!你的PHP CURL请求里,请求头的格式设置错了,这就是导致401未授权的核心原因——服务器根本没收到你的订阅密钥,自然拒绝了请求。
问题根源:请求头格式错误
在PHP的CURL中,CURLOPT_HTTPHEADER需要接收一个数组,每个元素必须是完整的"Header-Name: Value"格式字符串。但你现在把请求头的键和值拆成了两个独立的数组元素,相当于没正确传递密钥:
- 错误写法:
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Ocp-Apim-Subscription-Key", $subscriptionKey)); - 正确写法:
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Ocp-Apim-Subscription-Key: $subscriptionKey"));
修正后的完整PHP代码
另外,开启CURLOPT_HEADER后,响应内容会包含HTTP头信息,直接用json_decode会失败。下面提供两种实用版本:
版本1:关闭头信息(推荐,方便直接解析JSON)
header('Access-Control-Allow-Origin: ' . $_SERVER['SERVER_NAME']); $subscriptionKey = '你的实际订阅密钥'; // 务必填入正确密钥! $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://southcentralus.tts.speech.microsoft.com/cognitiveservices/voices/list'); // 修正后的请求头格式 curl_setopt($ch, CURLOPT_HTTPHEADER, array("Ocp-Apim-Subscription-Key: $subscriptionKey")); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 不需要头信息就关掉这个选项 // curl_setopt($ch, CURLOPT_HEADER, true); $response = curl_exec($ch); if($response === false) { echo 'Curl error: ' . curl_error($ch); } else { echo '请求执行成功<br><br>'; $voices = json_decode($response); if($voices === null) { echo 'JSON解析失败,响应内容:<br>' . $response; } else { // 这里可以处理拿到的语音列表 print_r($voices); } } curl_close($ch);
版本2:保留头信息并分离解析
如果需要查看HTTP头信息,可以手动分离头和响应主体:
header('Access-Control-Allow-Origin: ' . $_SERVER['SERVER_NAME']); $subscriptionKey = '你的实际订阅密钥'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://southcentralus.tts.speech.microsoft.com/cognitiveservices/voices/list'); curl_setopt($ch, CURLOPT_HTTPHEADER, array("Ocp-Apim-Subscription-Key: $subscriptionKey")); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); if($response === false) { echo 'Curl error: ' . curl_error($ch); } else { // 分离头信息和响应主体 $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); $header = substr($response, 0, $headerSize); $body = substr($response, $headerSize); echo 'HTTP头信息:<br>' . nl2br($header) . '<br><br>'; echo '响应主体:<br>'; $voices = json_decode($body); if($voices === null) { echo 'JSON解析失败,主体内容:' . $body; } else { print_r($voices); } } curl_close($ch);
额外注意事项
- 确认
$subscriptionKey填入了和JavaScript版本完全一致的密钥,别留空! - 检查你的服务器是否允许对外请求微软API,部分虚拟主机可能会限制CURL的外部请求。
- 如果还是有问题,开启CURL调试模式排查细节:
curl_setopt($ch, CURLOPT_VERBOSE, true);
内容的提问来源于stack exchange,提问作者TinMan
相关产品推荐
相关产品推荐

