PHP cURL错误:"服务器返回空响应"。

9

我有一个用于与Last.FM RESTful API接口的类函数 - 它的目的是获取我用户的最新曲目。以下是代码:

private static $base_url = 'http://ws.audioscrobbler.com/2.0/';

public static function getTopTracks($options = array())
{
  $options = array_merge(array(
    'user' => 'bachya',
    'period' => NULL,
    'api_key' => 'xxxxx...', // obfuscated, obviously
  ), $options);

  $options['method'] = 'user.getTopTracks';

  // Initialize cURL request and set parameters
  $ch = curl_init();
  curl_setopt_array($ch, array(
    CURLOPT_URL            => self::$base_url,
    CURLOPT_POST           => TRUE,
    CURLOPT_POSTFIELDS     => $options,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_TIMEOUT        => 30,
    CURLOPT_USERAGENT      => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'
  ));

  $results = curl_exec($ch);
  return $results;
}

这会返回"服务器未响应"。有人建议该错误来自于网络基础设施的某个故障;但在我的情况下,我不认为是这样。如果我通过命令行运行cURL请求,我可以得到数据;Last.FM服务正常并可访问。
在我联系相关人员之前,想先与您核实,看看是否存在导致此问题的代码问题。
谢谢! 答案: @Jan Kuboschek帮助我发现了这里可能出现的问题。通过给CURLOPT_POSTFIELDS提供一个关联数组,指定了特定的内容类型,这可能无法与某些RESTful服务一起使用。更明智的解决方案是手动创建一个URL编码版本的数据,并将其作为CURLOPT_POSTFIELDS传递。
有关更多信息,请查看:http://www.brandonchecketts.com/archives/array-versus-string-in-curlopt_postfields
5个回答

12
常见问题是URL中的空格-开头,中间或末尾。你检查过了吗? 编辑 - 根据下面的评论,空格不是问题。 我运行了你的代码并遇到了同样的问题-根本没有输出。我尝试了URL和GET请求,服务器与我通信。我会按照以下步骤操作: 1.使用以下内容作为$base_url:$base_url ='http://ws.audioscrobbler.com/2.0/?user=bachya&period=&api_key=xxx&method=user.getTopTracks'; 2.从你的请求中删除帖子字段。 编辑 我将你的代码移到类外面,因为我没有其他部分并对其进行了修改。以下代码对我来说完美地运行。如果这些更改对你不起作用,我建议你的错误在于不同的函数。
<?php


function getTopTracks()
{
  $base_url = 'http://ws.audioscrobbler.com/2.0/?user=bachya&period=&api_key=8066d2ebfbf1e1a8d1c32c84cf65c91c&method=user.getTopTracks';
  $options = array_merge(array(
    'user' => 'bachya',
    'period' => NULL,
    'api_key' => 'xxxxx...', // obfuscated, obviously
  ));

  $options['method'] = 'user.getTopTracks';

  // Initialize cURL request and set parameters
  $ch = curl_init($base_url);
  curl_setopt_array($ch, array(
    CURLOPT_URL            => $base_url,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_TIMEOUT        => 30,
    CURLOPT_USERAGENT      => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'
  ));

  $results = curl_exec($ch);
  return $results;
}

echo getTopTracks();

?>

不幸的是,那不是问题 - 我更新了我的原始帖子以显示我使用的URL($base_url)。谢谢。:-\ - ABach
已更新我的回答。如果这仍然不起作用,请告诉我。由于服务器告诉我需要有效的API密钥,因此无法进一步测试。 - Jan K.
好的,我试过了 - 它似乎要多等一会儿才能“工作”。我使用var_dump函数来输出curl_exec的结果,但返回值是false... 我不想公开我的API密钥,但它们很容易获得。 - ABach
请在此处检查:http://www.last.fm/api/account - 感谢您和我一样的热情! :) - ABach
1
我曾经遇到过同样的问题...实际上,空格会对curl请求造成问题...我的url中有关键字=iphone 5,但我总是得到空响应...当我将关键字=iphone+5替换后,它就正常工作了 :) - casper123
显示剩余2条评论

8
服务器已收到您的请求,但发送了一个空响应。检查curl_getinfo($ch, CURLINFO_HTTP_CODE)的结果,以找出服务器是否响应了HTTP错误代码。
更新:好的,所以服务器响应100 Continue HTTP状态码。在这种情况下,这应该解决您的问题。
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));

我在这里找到了这个链接:PHP和cURL:禁用100-continue头部。希望它能起作用!


变量转储这返回 100 - 有帮助,希望如此? - ABach
1
另外更新一下:Jan的解决方案使用GET而不是POST,正如Michał所指出的那样,这对于读取API调用实际上更好。 100 Continue的内容不适用于GET,因此它很好地避免了真正的问题。如果您还想访问写入服务,则应为这些调用使用POST,并尝试我的答案。 - cygri

1

下面是从Last.FM获取专辑信息的代码,即使返回错误也能获取:

函数:

function getAlbum($xml,$artist,$album)
{
  $base_url = $xml;
  $options = array_merge(array(
    'user' => 'YOUR_USERNAME',
    'artist'=>$artist,
    'album'=>$album,
    'period' => NULL,
    'api_key' => 'xYxOxUxRxxAxPxIxxKxExYxx', 
  ));

  $options['method'] = 'album.getinfo';

  // Initialize cURL request and set parameters
  $ch = curl_init($base_url);
  curl_setopt_array($ch, array(
    CURLOPT_URL            => 'http://ws.audioscrobbler.com/2.0/',
    CURLOPT_POST           => TRUE,
    CURLOPT_POSTFIELDS     => $options,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_TIMEOUT        => 30,
    CURLOPT_HTTPHEADER        => array( 'Expect:' ) ,
    CURLOPT_USERAGENT      => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'
  ));

  $results = curl_exec($ch);
  unset ($options);
  return $results;
}

用法:

// Get the XML
$xml_error = getAlbum($xml,$artist,$album);

// Show XML error
if (preg_match("/error/i", $xml_error)) {
    echo " <strong>ERRO:</strong> ".trim(strip_tags($xml_error));
}

1

我遇到了同样的问题。我的Http_code返回200,但是我的响应为空。这可能有很多原因,正如我所经历的那样。

--你的头部信息可能不正确

CURLOPT_HTTPHEADER => array('Content-Type:application/json', 'Expect:')

--您可能需要在curl中将数据作为post字段发送,而不是像url?p1=a1&p2=a2这样附加到URL。
$data = array (p1=>a1, p2=>a2)
CURLOPT_POSTFIELDS => $data

因此,您的选项数组将类似于以下内容

array(
    CURLOPT_URL => $url,
    CURLOPT_FAILONERROR => TRUE, // FALSE if in debug mode
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_TIMEOUT => 4,
    CURLOPT_HTTPHEADER => array('Content-Type:application/json', 'Expect:'),
    CURLOPT_POST => TRUE,
    CURLOPT_POSTFIELDS => $data,
);

0
根据Last.FM API文档,您应该使用GET方法而不是POST来传递参数。当我将POST更改为GET时,我收到了关于无效密钥的答复。

我在那份文件中没有看到任何指定通过 GET 请求传递参数的要求。你能告诉我具体在哪里吗? - ABach
1
一般来说,您将会发送一个表示为“package.method”的方法参数以及特定于该方法的参数到根URL。例如:http://ws.audioscrobbler.com/2.0/?method=artist.getSimilar&api_key=xxx...如果您正在访问写服务,则需要将请求提交为HTTP POST请求。 - Michał Pipa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接