reCAPTCHA验证报错排查:file_get_contents未指定Content-Type
file_get_contents的Content-Type警告及功能异常问题 Hey there, let's tackle this reCAPTCHA issue step by step. The error you're seeing is a direct result of missing the Content-Type header in your HTTP request to Google's reCAPTCHA verification endpoint, and there are a couple other small issues in your code that might be causing unexpected behavior too.
1. 修复Content-Type警告(错误根源)
$verify = file_get_contents($url, false, $context)抛出警告的原因是你的$options数组没有显式设置Content-Type请求头。虽然http_build_query()会将数据格式化为application/x-www-form-urlencoded格式,但PHP的流上下文不会自动添加这个头,所以我们需要手动指定。
修改你的$options数组,添加请求头:
$options = array( 'http' => array ( 'method' => 'POST', 'header' => "Content-Type: application/x-www-form-urlencoded\r\n", 'content' => http_build_query($data) ) );
2. 修复二次请求中未定义的$query变量
在你后续的$content数组代码中,你使用了未定义的$query变量来计算Content-Length,这会在修复第一个问题后引发新的错误。如果这个变量是用来指代http_build_query($data)生成的编码数据,需要先定义它:
$encodedData = http_build_query($data); $content = array ( 'http' => array ( 'header' => "Content-Type: application/x-www-form-urlencoded\r\n". "Content-Length: ".strlen($encodedData)."\r\n". "User-Agent:MyAgent/1.0\r\n", 'method' => 'POST', 'content' => $encodedData ) );
3. 用Laravel的Request对象替代$_POST
既然你在Laravel控制器中开发,建议使用注入的$request对象来获取请求参数,而不是直接访问$_POST,这更符合框架规范且更安全:
$response = $request->input('g-recaptcha-response'); // ... $data = array( 'secret' => '6LcwXi8UAAAAAE9zNCVfqwDOIWNazNgdK-0wQv9L', 'response' => $request->input('g-recaptcha-response') );
4. reCAPTCHA功能的额外检查项
- 再次确认你的reCAPTCHA密钥是否正确(看起来你用的是v2密钥,如果前端也是reCAPTCHA v2的话没问题)。
- 验证密钥关联的域名是否和表单所在域名一致(Google会阻止未授权域名的请求)。
- 确保前端正确渲染了reCAPTCHA组件,并且表单提交时确实发送了
g-recaptcha-response参数。
整合以上修改,你的message方法最终代码如下:
public function message(Request $request) { $response = $request->input('g-recaptcha-response'); $url = 'https://www.google.com/recaptcha/api/siteverify'; $data = array( 'secret' => '6LcwXi8UAAAAAE9zNCVfqwDOIWNazNgdK-0wQv9L', 'response' => $response ); // For debug purpose (remove comments) // dd($request->all()); $encodedData = http_build_query($data); $options = array( 'http' => array ( 'method' => 'POST', 'header' => "Content-Type: application/x-www-form-urlencoded\r\n", 'content' => $encodedData ) ); $context = stream_context_create($options); $verify = file_get_contents($url, false, $context); $captchaSuccess = json_decode($verify); if (!$captchaSuccess->success) { return redirect('/')->with('success', 'You are a bot! Go away!'); } else { $content = array ( 'http' => array ( 'header' => "Content-Type: application/x-www-form-urlencoded\r\n". "Content-Length: ".strlen($encodedData)."\r\n". "User-Agent:MyAgent/1.0\r\n", 'method' => 'POST', 'content' => $encodedData ) ); // 这里添加你后续的业务逻辑... } }
以上修改应该能解决Content-Type警告,同时修复相关的reCAPTCHA验证问题。
内容的提问来源于stack exchange,提问作者Japracool

