Nginx 阻止某些应用内置浏览器访问

首先我们需要定义阻止哪些应用,比如本站预设阻止 QQ 系浏览器访问

    if ($http_user_agent ~* (MQQBrowser|QQ|TIM) ) {
            return 403;
    }

但是这样子设置太不友好了,有可能会被认为是 Nginx 不会配

那我们就简单美化一下网站

我们用一个自定义的页面好了,稍微把 Nginx 的页面修改一下

<html>
<head><title>Built-in browser Forbidden</title></head>
<body>
<center><h1>Visit from some app built-in browser is Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>

这样写可能太过精简了,大概还是需要在后面加上几行

<!-- a padding to disable MSIE and Chrome friendly error page -->

接着我们再把 Nginx 的配置调整一下

    location /ban-builtin {
            root $WEBROOT;
            rewrite ^ /403-ban-built-in.html break;
    }

    if ($http_user_agent ~* (MQQBrowser|QQ|TIM) ) {
            set $shouldban "1";
    }

    if ($request_uri != /ban-builtin) {
            set $shouldban "${shouldban}0";
    }

    if ($shouldban = "10") {
            return 307 $scheme://$host/ban-builtin;
    }

如果不加上第三个语句判别的话,会导致无限重定向。

那现在我们也可以主动访问一下来试试


有朋友说这样对使用浏览器访问太不友好了,要想个办法用更好的方式来做

那还能怎么办, Nginx 肯定是做不到了,大概还是需要一个 php 页面

<?php
    $UA = $_SERVER['HTTP_USER_AGENT'];
    //if (str_contains($UA, "QQ") || str_contains($UA, "MQQBrowser") || str_contains($UA, "TIM")) { // PHP8
    if (strpos($UA, "QQ") || strpos($UA, "MQQBrowser") || strpos($UA, "TIM")) {
        http_response_code(403);
        echo <<<EOT
<html>
<head><title>Built-in browser Forbidden</title></head>
<body>
<center><h1>Visit from some app built-in browser is Forbidden</h1>请点击右上角使用外部浏览器打开<br>
<hr><center>nginx</center>
</body>
</html>
EOT;
        die();
    }
    $redirect_location = '/';
    if (isset($_GET["to"])) {
        $redirect_location = $_GET["to"];
    }
    header("HTTP/1.1 307 Temporary Redirect");
    header("Location: //".$_SERVER['HTTP_HOST'].$redirect_location);
    die();
?>

(PHP7 还没有 str_contains 函数,坑了我一把)

然后稍微的把 Nginx 配置调整一下

    if ($shouldban = "10") {
            return 307 $scheme://$host/redirect.php?to=$request_uri;
    }

现在就是访问新的页面了