检查 PHP 脚本是否用作 <img> 源

Check if PHP script is used as <img> source

是否可以确定 PHP 脚本的输出将用作图像还是完整站点?

我需要这样的东西:

<?php
    if(clientRequestedImage()) {
        header("Content-Type: image/png");
        readfile("image.png");
    } else {
        readfile("image-wrapped.html");
    }
?>

所以当我稍后使用 <img src="script.php"> 时,会显示一个图像,当我使用地址栏或 link 打开脚本时,会出现一个 HTML 文件。

我应该如何实现功能clientRequestedImage

类似问题:Check if site is inside iframe

大概要可重复使用,您还需要知道图像名称或其他要引用的内容,因此图像标签可能如下:

<img src="script.php?image=logo">

然后(这不安全,您需要将获取的数据列入白名单或以其他方式清理):

if(isset($_GET['image'])) {
    header("Content-Type: image/png");
    readfile($_GET['image'] . "image.png");
} else {
    readfile("image-wrapped.html");
}

如果没有,那么简单如:

<img src="script.php?image">

或:

<img src="script.php?html">    

然后检查 isset($_GET['image']) 等...

免责声明:这只是一种预感,我不确定这是否适用于所有浏览器(应该适用于最新的 Chrome 和 Firefox,至少是这样我测试了)。

您可以解析客户端的 Accept HTTP header。客户端使用 Accept header 指定浏览器应将其响应发送到的媒体类型。此 header 的示例是:

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept: image/png,image/*;q=0.8,*/*;q=0.5

Chrome 和 Firefox 似乎 在请求常规站点时总是发送 Accept: text/html,... header,Accept: image/... 加载由 <img> 标签嵌入的图像时。

您可以通过 $_SERVER['HTTP_ACCEPT'] 变量在 PHP 中访问此 header。所以你可能能够做这样的事情:

$acceptedTypes = explode(',', $_SERVER['HTTP_ACCEPT']);
if (strstr($acceptedTypes[0], 'text/html') === 0) {
    // Output as HTML page
} else if (strstr($acceptedTypes[0], 'image/') === 0) {
    // Output as image
}

You didn't answer any of my two questions. If I wanted two different URLs, I would use <img src="image.png"> and <a href="site.html"> directly..

这条评论让我想到了 URL 重写。正如您 link 文章中甚至提到的那样,HTTP Referrer 只是 3 个选项中的 1 个。就像@AbraCadaver 提到的那样,选项 3 是最好的,使用 URL 参数。

如果你坚持在一个脚本中完成,你必须利用 URL 重写。这允许您屏蔽 URL 参数。这样你就有了一些条件让 PHP 知道要呈现什么。

以您的示例为例,当浏览器呈现页面时,它会创建一个 HTTP 请求来下载由其属性 SRC 标记 <IMG> 指定的图像文件。浏览器为 URL 创建一个 GET 请求,即 www.example.com/image.png,并且可能会也可能不会修改 headers 的引荐来源网址。 <A> 标签根据 href 属性呈现 link,当用户在浏览器中单击此 link 时,浏览器会为 URL(听起来很熟悉?),即 www.example.com/site.html.

使用URL Rewrite,我们可以检查这两个URL并将流量定向到相同的PHP脚本,在后台调整URL参数。 /image.png的请求可以变成script.php?image=image.png/site.html的请求可以变成script.php?site=site.html