如何通过从PHP缩短的URL进行一系列重定向后如何找到最后一个(最终)URL

问题描述 投票:1回答:2

我为WordPress构建了一个自定义插件,人们无需注册/登录即可发布,而只需再次确认密码即可发布。它一直运行良好,没有垃圾邮件,但有人开始发布垃圾邮件链接。

我写了一个插件来检测基于IP地址的模式,然后阻止IP并删除所有被阻止者的帖子。但是,我认为该垃圾邮件发送者正在使用一种欺骗或切换IP地址并从其他IP地址开始发布的工具。我发现的一个共同点是,经过一系列重定向后,链接将转到相同的URL。

我已经尝试了以下功能来跟踪目的地,但是没有运气。

myfunction( $url ){
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  curl_setopt($ch, CURLOPT_HEADER, false);
  curl_setopt($ch, CURLOPT_NOBODY, true);
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
  curl_exec($ch);
  $lastUrl = curl_getinfo($ch);
  curl_close($ch);
  return $lastUrl;
}

我也尝试过从链接中获取标头信息,但不走运。

因此,我尝试了许多在线工具,这些工具从链接中获取了最终URL,但没有一个起作用。

此垃圾邮件发送者使用的URL缩短服务是http://urnic.com/

我不认为它正在执行JavaScript重定向,因为它与从我的Chrome中关闭的JS一起工作。

php php-curl
2个回答
0
投票

您可以使用curl的CURLOPT_FOLLOWLOCATION + CURLINFO_EFFECTIVE_URL查找最终地址,只要您说的重定向是HTTP重定向(例如HTTP 3xx 300 Multiple Choices301 Moved Permanently302 Found307 Temporary Redirect等),

function get_final_url(string $redirect_url):string{
$ch=curl_init($redirect_url);
curl_setopt_array($ch,array(
    CURLOPT_FOLLOWLOCATION=>1,
    CURLOPT_ENCODING=>'',
    CURLOPT_USERAGENT=>'many_websites_block_UAless_requests',
    CURLOPT_RETURNTRANSFER=>1, // ideally we should use CURLOPT_NOBODY but some websites respond differently to HEAD requests, so using GET requests is the safest option =/ (also if you're worried about ram usage, you should set CURLOPT_OUTFILE to /dev/null or enable CURLOPT_WRITEFUNCTION)
));
curl_exec($ch);
$ret=curl_getinfo($ch,CURLINFO_EFFECTIVE_URL);
curl_close($ch);
return $ret;
}

ps!未经测试,可能是拼写错误或其他内容,但理论上应该可以。)]

正如我在代码注释中提到的,如果您担心巨大的响应,则可以优化该函数以使用较少的ram(CURLOPT_RETURNTRANSFER将整个响应置于ram中,可以通过使用空的CURLOPT_WRITEFUNCTION进行修复)

无论如何,那应该返回最终网址。


0
投票

您可以使用preg_match并捕获位置网址。它非常适合我。

$curlhandle = curl_init();
curl_setopt($curlhandle, CURLOPT_URL, $url);
curl_setopt($curlhandle, CURLOPT_HEADER, 1);
curl_setopt($curlhandle, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($curlhandle, CURLOPT_RETURNTRANSFER, 1);
$final = curl_exec($curlhandle);
if (preg_match('~Location: (.*)~i', $final, $lasturl)) {
   $loc = trim($lasturl[1]);
}

echo $loc;
© www.soinside.com 2019 - 2024. All rights reserved.