PHP:检查URL是否重定向?
我已经在每个页面上实现了一个我想限制未登录用户的函数。该功能自动将访问者重定向到他或她未登录的情况下的登录页面。PHP:检查URL是否重定向?
我想使一个PHP函数从外部服务器运行并遍历多个设置的URL(数组包含每个受保护站点的URL)以查看它们是否被重定向。因此,我可以轻松确定每个页面上的防护是否已启动并运行。
这怎么办?
谢谢。
$urls = array(
'http://www.apple.com/imac',
'http://www.google.com/'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
foreach($urls as $url) {
curl_setopt($ch, CURLOPT_URL, $url);
$out = curl_exec($ch);
// line endings is the wonkiest piece of this whole thing
$out = str_replace("\r", "", $out);
// only look at the headers
$headers_end = strpos($out, "\n\n");
if($headers_end !== false) {
$out = substr($out, 0, $headers_end);
}
$headers = explode("\n", $out);
foreach($headers as $header) {
if(substr($header, 0, 10) == "Location: ") {
$target = substr($header, 10);
echo "[$url] redirects to [$target]<br>";
continue 2;
}
}
echo "[$url] does not redirect<br>";
}
超级甜蜜的解决方案! Tack Adam :) – Industrial 2010-06-03 11:12:06
您还可以使用curl_getinfo($ ch,CURLINFO_HTTP_CODE)来读取状态码(301或302) – baloo 2010-06-03 12:11:10
如果您使用'curl_setopt($ handle,CURLOPT_NOBODY,true),您还可以节省一些带宽和处理能力。 '。这只会发送一个HTTP HEAD请求。这样你就不必切断身体。另请参阅此文章:http://schlitt.info/opensource/blog/0606_sending_head_requests_with_extcurl.html – chiborg 2012-04-26 21:25:28
我不明白你的问题。 你有一个包含URL的数组,你想知道用户是否来自某个列出的URL? 如果我正确理解你的追求:
$urls = array('http://url1.com','http://url2.ru','http://url3.org');
if(in_array($_SERVER['HTTP_REFERER'],$urls))
{
echo 'FROM ARRAY';
} else {
echo 'NOT FROM ARR';
}
推举者很弱 – 2010-06-03 10:12:15
更新了问题。我想调用数组中的每个url来查看它们是否停留在set url或重定向到登录页面。 – Industrial 2010-06-03 10:14:27
您可以使用会话,如果会话阵列没有设置,该URL重定向到一个登录页面。 。
这就是我的安全基础,但不会让我能够看到一个数组中的页面是否重定向。 – Industrial 2010-06-03 10:15:52
我不确定这是否真的作为安全检查有意义。
如果你担心文件被直接调用而没有你的“用户登录?”检查正在运行,您可以执行许多大型PHP项目所做的事情:在*包含文件(安全检查正在进行)中定义一个常数BOOTSTRAP_LOADED
或其他内容,并在每个文件中检查是否设置了该常量。
测试非常好,安全测试甚至更好,但我不确定您想要发现哪种缺陷?对我而言,这个想法感觉像是浪费时间,不会带来任何真正的额外安全。
只要确保您的脚本die()
s在header("Location:...")
之后重定向。这对于阻止额外的内容在标题命令之后显示是必不可少的(因为重定向标题仍将被发出,所以缺少die()将不会被您的想法所捕获...)
如果你真的想要这样做,你也可以使用像wget
这样的工具并为它提供一个URL列表。让它将结果提取到一个目录中,然后检查(例如,通过查看应该相同的文件大小)每个页面是否包含登录对话框。只是添加另一个选项...
是否要检查HTTP代码以查看它是否是重定向?
$params = array('http' => array(
'method' => 'HEAD',
'ignore_errors' => true
));
$context = stream_context_create($params);
foreach(array('http://google.com', 'http://*.com') as $url) {
$fp = fopen($url, 'rb', false, $context);
$result = stream_get_contents($fp);
if ($result === false) {
throw new Exception("Could not read data from {$url}");
} else if (! strstr($http_response_header[0], '301')) {
// Do something here
}
}
我修改了Adam Backstrom的答案并实现了chiborg建议。 (只下载HEAD)。它还有一件事:它会检查重定向是在同一台服务器的一个页面上还是不存在。例如:terra.com.br重定向到terra.com.br/portal。 PHP会像重定向一样考虑它,并且它是正确的。但我只想列出重定向到另一个URL的那个URL。我的英语不好,所以,如果有人发现了一些很难理解的东西,并且可以编辑它,那么欢迎您。
function RedirectURL() {
$urls = array('http://www.terra.com.br/','http://www.areiaebrita.com.br/');
foreach ($urls as $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// chiborg suggestion
curl_setopt($ch, CURLOPT_NOBODY, true);
// ================================
// READ URL
// ================================
curl_setopt($ch, CURLOPT_URL, $url);
$out = curl_exec($ch);
// line endings is the wonkiest piece of this whole thing
$out = str_replace("\r", "", $out);
echo $out;
$headers = explode("\n", $out);
foreach($headers as $header) {
if(substr(strtolower($header), 0, 9) == "location:") {
// read URL to check if redirect to somepage on the server or another one.
// terra.com.br redirect to terra.com.br/portal. it is valid.
// but areiaebrita.com.br redirect to bwnet.com.br, and this is invalid.
// what we want is to check if the address continues being terra.com.br or changes. if changes, prints on page.
// if contains http, we will check if changes url or not.
// some servers, to redirect to a folder available on it, redirect only citting the folder. Example: net11.com.br redirect only to /heiden
// only execute if have http on location
if (strpos(strtolower($header), "http") !== false) {
$address = explode("/", $header);
print_r($address);
// $address['0'] = http
// $address['1'] =
// $address['2'] = www.terra.com.br
// $address['3'] = portal
echo "url (address from array) = " . $url . "<br>";
echo "address[2] = " . $address['2'] . "<br><br>";
// url: terra.com.br
// address['2'] = www.terra.com.br
// check if string terra.com.br is still available in www.terra.com.br. It indicates that server did not redirect to some page away from here.
if(strpos(strtolower($address['2']), strtolower($url)) !== false) {
echo "URL NOT REDIRECT";
} else {
// not the same. (areiaebrita)
echo "SORRY, URL REDIRECT WAS FOUND: " . $url;
}
}
}
}
}
}
function unshorten_url($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
$out = curl_exec($ch);
$real_url = $url;//default.. (if no redirect)
if (preg_match("/location: (.*)/i", $out, $redirect))
$real_url = $redirect[1];
if (strstr($real_url, "bit.ly"))//the redirect is another shortened url
$real_url = unshorten_url($real_url);
return $real_url;
}
你总是可以尝试添加:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
,因为302是指它移动,使卷曲呼叫跟踪,并返回无论移动网址的回报。
这......实际上是正确的答案。谢谢!看起来如果没有这个curl就会停止它首先收到的内容,并且如果有的话就不会遵循重定向。谢谢!!! – 2014-08-23 04:21:47
我用卷曲,只需要头,之后我比较我的网址和URL的头卷曲:
$url="http://google.com";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, '60'); // in seconds
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$res = curl_exec($ch);
if(curl_getinfo($ch)['url'] == $url){
$status = "not redirect";
}else {
$status = "redirect";
}
重定向怎么样?从什么客户调用?登录时或未登录时?做什么的?脚本是否必须处理会话cookie和其他复杂的事情? – 2010-06-03 10:02:17
请定义“重定向的URL”。 – 2010-06-03 10:02:38
请参阅[如何确定URL是否在PHP中重定向?](http://*.com/questions/427203/how-can-i-determine-if-a-url-redirects-in-php/481377# 481377) – 2010-06-03 10:02:54