为每个 cURL 请求返回 AJAX 结果
Posted
技术标签:
【中文标题】为每个 cURL 请求返回 AJAX 结果【英文标题】:return AJAX result for each cURL Request 【发布时间】:2013-11-08 00:51:05 【问题描述】:基本上,我的想法是做某种形式的“live cURL results”系统,当每个请求被执行时,它会产生 live results,例如我会有一个包含需要通过 cURL 请求访问的网站列表的表,在每个 cURL 响应的结果中,我需要使用 AJAX 函数将数据发送回我的页面我最初调用了执行此操作的文件请求循环
<?
foreach($database['table'] as $row)
curl_init($row['url']);
//the rest of the cURL request etc...
//SEND cURL RESPONSE BACK TO AJAX AFTER EACH ROW!!!
<?
然后我希望它在每个 cURL 响应发生时返回结果,而不是等待完整的脚本完成后再一次返回所有响应。
这可能吗?如果是这样,我还会使用普通的 AJAX 请求吗?
【问题讨论】:
AJAX 是客户端,通过 javascript。 cURL 是服务器端的,由 php 提供。你想要什么?您还应该注意,您的curl_init()
将返回一个资源句柄,您应该使用一个变量来保存它。
如果有帮助,您可以 flush() 获得的任何结果,但正如 Shivan Raptor 所说,它们是两种不同的技术,所以很难说,除非您打算使用 AJAX 向“API”发送垃圾邮件请求每
【参考方案1】:
这个怎么样?
您将实体过程分解为 3 个
流程 1
您向访问数据库的 php 页面发送 ajax 请求,并将 url 列表发送回浏览器页面。 [简单地回显 Urls] [使用分隔符 '|'分隔结果 url。]
流程 2
上述进程的 ajax 成功处理函数现在将调用一个新的 JavaScript 函数来执行以下操作。
将 url 列表拆分为一个数组。
流程 3 使用另一个 ajax 函数将 urls 列表一个一个发送到服务器。
这样一次只处理一个url,结果一处理就发回
下面是 JavaScript 中函数调用的原型,代码不是真实的,但你可以大致了解它的工作原理。
function ajaxCall_1()
// get url lsit from server
.onSuccess
process_url(data);
function process_url(data)
var url_array = data.split('|')
fetch_urls(url_array,0); // sends the first url for processing
function fetch_urls(url_array,position)
if(position < url_array.lenght) // not exceeding the array count
ajax_call2(url_array[position],url_array,position);
function ajaxCall_2(url,url_array,position)
// get url acced by curl and send back the result
.onSuccess
// do whatever with the data you want
fetch_urls(url_array,position++) // or position+1 // to fetch the next url
【讨论】:
【参考方案2】:在构建网站表格的 php 脚本中,只需一次执行所有 ajax 请求,然后在返回时将结果返回到表格行。
【讨论】:
【参考方案3】:您不能在编写消息时返回消息,除非您正在写入套接字。 在对 PHP 脚本的正常 AJAX 调用中,这是不可能的,您只能编写一次响应并返回它。
【讨论】:
这是错误的。 AJAX 具有readyState == 3
,即incomplete
,它为您提供在请求完成之前服务器已发送给您的客户端的所有内容。例如,这也可以用于控制下载速度,只需在特定时间间隔内刷新所需的数据量即可。
这不是 AJAX 的问题,而是 PHP 的部分,因为当他处理来自数据库的行时,无法输出数据。 PHP 一次输出所有内容。
这仍然不正确。 PHP 甚至可以在完成之前将数据刷新到客户端。事实上,除非您使用输出缓冲区之类的东西,否则它会自动执行此操作,这会阻止它发送内容。尝试在单行 html 之后设置标题,它甚至会告诉您自己一旦发送数据就无法修改标题。使用输出缓冲区,可以使用ob_flush()
和使用此方法的所有其他方法,例如ob_end_flush()
。【参考方案4】:
在您的情况下,您可以使用flush
或ob_flush
。
此命令会强制将输出数据发送到浏览器,但在某些情况下可以在中间软件(例如 nginx)中停止
还有另一个问题。在您的脚本发送数据之前,页面不会触发加载事件。这么多js脚本都行不通。
在你的情况下,我将制作另一个系统。
-
您的 curl 脚本会在短时间内从 crontab 之一运行。
curl 的所有结果都保存在数据库中。
Ajax 脚本调用 php 后端输出最后的结果并将它们从数据库中删除。
这在任何情况下都有效(大多数情况下):)
【讨论】:
【参考方案5】:我看到了两种实现目标的方法。
-
为每个 cURL 请求执行单独的 AJAX 请求。这样您就不必“找到棘手的解决方案”,一切都会按预期进行
使用
curl_multi_*
同时执行所有请求,然后将所有数据集中返回。通过这种方式,您可以打开脚本以解决潜在的负载问题,以防有许多用户同时执行多个请求
我在不同的项目中都使用了它们,如果您需要,可以提供更多详细信息。
【讨论】:
【参考方案6】:好吧,我实际上并没有得到你想要做的事情,我认为 WebSockets 会帮助你 Web Sockets Tutorail
【讨论】:
【参考方案7】:您可以逐个存储 curl 请求的结果,并通过在每 N 秒(假设 5 秒)后执行一次请求来检索该结果。
在这一部分中,我们将 curl 请求的输出存储在某处。这里有一些修改过的源代码,它获取输出并调用一个函数将其存储在队列中:
//these two lines will be mostly same for all request
//so i put them out of the loop
curl_init($ch);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//these two lines will be mostly same for all request
//so i put them out of the loop
curl_init($ch);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
foreach($database['table'] as $row)
// set URL and other appropriate options which
//vaires from request to requeste
curl_setopt($ch, CURLOPT_URL, $row['url']);
//grabbing the output in $output
$output = $curl_exec();
put_it_to_the_queue($output);
curl_exec($ch);
现在put_it_to_the_queue($output)
会做什么?它将输出存储在某个地方,以便其他一些资源可以从那里获取它们。为了简单起见,让我们把它放在你的会话中。
function put_it_to_the_queue($output)
//Or you can store in sql lite or in a file or somewhere else
array_push($_SESSION['outputs']);
问题是客户将如何应对这种不同的情况。
让客户端第一次调用服务器以开始获取 url,然后完全忘记这一点。
$.get('start.php');
我们需要得到输出。如何做到这一点?创建另一个 php 页面 pull.php
,如果队列中有任何内容,它将发送输出。
echo array_shift($_SESSION['outputs']);
这是检索输出的客户端代码。 在向服务器发送第一个请求后放置此代码。
//delay is in ms
//5 is the value of N seconds
//we will retrieve the output form
var delay = 5 * 1000;
window.setInterval(function()
$.get('pull.php',function(response)
//do something with the reponse here
alert(response);
)
, delay);
注意
此解决方案并非万无一失。如果您有一个重听的网站,您需要使用更精确的存储来存储 html 请求的结果,并且在这种情况下您需要使用推送方法而不是拉取方法。
要了解更多关于我在这里使用的功能:
-
array_push
array_shift
window.setInterval
【讨论】:
【参考方案8】:对 PHP 脚本的 Ajax 请求的概念是,当您进行 Ajax 调用时,它会执行请求的 PHP 脚本并将整个响应发送到 Ajax。
根据您的要求,PHP 脚本不会向 Ajax 调用发送部分响应,而是 PHP 脚本可以一次发送 cUrl 响应集合。
要解决此问题,您可以执行以下步骤
在 PHP 和两个 Ajax 调用中创建两个操作。
将所有 URl 从 Table 发送到第一个 Ajax 调用的操作。
获得第一个响应(URL 列表)后,您可以执行系列 Ajax 调用(在每个获取的 URls 的循环中)。
此 Ajax 调用将请求执行 cUrl 的第二个 PHP 脚本 获取响应。
然后您将此响应发送回已启动的 Ajax 调用。然后用那个 cUrl 响应做你想做的事情。
希望对你有所帮助。
【讨论】:
以上是关于为每个 cURL 请求返回 AJAX 结果的主要内容,如果未能解决你的问题,请参考以下文章