嗨,老铁,欢迎来到我的博客!

如果觉得我的内容还不错的话,可以关注下我在 segmentfault.com 上的直播。我主要从事 PHP 和 Java 方面的开发,《深入 PHP 内核》作者之一。

[视频直播] PHP 进阶之路 - 亿级 pv 网站架构的技术细节与套路 直播中我将毫无保留的分享我这六年的全部工作经验和踩坑的故事,以及会穿插着一些面试中的 考点难点加分点

菜单开关

周梦康 发表于 2018-02-01 766 次浏览 标签 : Nginx

缘起

前几天发现一个电子书非常棒,但是是 github 上的,总是打不开,而正好我的服务器是在香港的,所以我想做一个镜像。

方案一

做了如下配置:

location ^~ /book-c/
{
        proxy_pass http://akaedu.github.io/book/;
        proxy_redirect off;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
}

浏览了下,都 ok,但是有几点不太好

  1. 如果以后我发现类似的书很好,都要增加一个 nginx 配置。
  2. 如果原始网站完全无法访问了,我这边也挂了,不能缓存到我本地服务器。
  3. 我想修改网页内容也不太好操作,比如我想加上原作者的版权和原始访问地址说明等。

完全采集过来,我也懒得写脚本去跑,最终走上了下面这段踩坑路。

尝试改进

所以尝试了如下做法

rewrite ^/book-(.*?)/          /index.php?m=Book&a=show&book=$1 last;
class BookAction extends Action{

    private $uri;

    public function show(){
        $book = $_GET['book'];

        if (!method_exists($this,$book)){
            $this->error404();
        }

        try{
            $this->$book();
        }catch (Exception $e){
            $this->error404();
        }
    }

    /**
     * http://akaedu.github.io/book/
     */
    private function c(){
        $baseUrl = "http://akaedu.github.io/book/";
        $url = $baseUrl.$this->uri;
        echo file_get_contents($url);
    }
}

又遇到了一个问题,当我访问 https://mengkang.net/book-c/styles.css 则无法 rewrite 匹配到了。
原因是 nginx 优先匹配了

location ~ .*\.(js|css)?$
{
    expires      12h;
}

正则匹配优先级关系 https://segmentfault.com/a/1190000002797606

方案二

添加一条

location ~ /book-.*?/
{
    rewrite ^/book-(.*?)/     /index.php?m=Book&a=show&book=$1 last;
}

location ^~不支持正则的,所以没法用

采坑小记

如果是使用的location ~ /book-.*/,根据正则就是贪婪模式,那么

https://mengkang.net/book-c/images/sortsearch.theta.png

匹配到的就是/book-c/images/,也就是说rewrite里面的$1就是c/images,这样和我们的预期相悖的。

故障:无法匹配到 css 文件

$ wget -S https://mengkang.net/book-c/styles.css -O /dev/null
--2018-02-01 13:13:36--  https://mengkang.net/book-c/styles.css
Resolving mengkang.net... 203.195.188.207
Connecting to mengkang.net|203.195.188.207|:443... connected.
HTTP request sent, awaiting response...
  HTTP/1.1 200 OK
  Server: nginx
  Date: Thu, 01 Feb 2018 05:13:38 GMT
  Content-Type: text/html; charset=UTF-8

所有内容的输出默认都是text/html,那么也就是我需要对文件的后缀判断咯。感觉自己给自己挖坑,不如直接采集得了

<?php

class BookAction extends Action{

    const BOOK_SAVE_DIR = "/data/book/";

    private $uri;
    private $baseUrl;

    private $book;
    private $bookname;

    public function show(){
        $book = $_GET['book'];
        $this->book = $book;

        $this->uri = str_replace("/book-{$book}/","",$_SERVER['REQUEST_URI']);

        if (!method_exists($this,$book)){
            $this->error404();
        }

        try{
            $this->$book();
        }catch (Exception $e){
            $this->error404();
        }
    }

    /**
     * http://akaedu.github.io/book/
     */
    private function c(){
        $this->baseUrl = "http://akaedu.github.io/book/";
        $url = $this->baseUrl.$this->uri;
        $this->output($url);
    }

    private function output($url){
        $ext = pathinfo($url,PATHINFO_EXTENSION);

        if (!$ext) {
            $url = $url."/index.html";
            $ext = "html";
        }

        switch ($ext){
            case "css":
                header("Content-Type: text/css; charset=UTF-8");
                break;
            default:
                header("Content-Type: text/html; charset=UTF-8");
                break;
        }

        // 如果已经缓存
        $filename = self::BOOK_SAVE_DIR.$this->book."/".str_replace($this->baseUrl,"",$url);

        if (file_exists($filename)){
            $data = file_get_contents($filename);
        }else{
            $data = file_get_contents($url);

            $dir = dirname($filename);

            if (!file_exists($dir)){
                mkdir($dir,755,true);
            }

            file_put_contents($filename,$data);
        }

        // 增加原始版权说明


        echo $data;
    }
}

上线

https://mengkang.net/book-c/

嗨,老铁,欢迎来到我的博客!

如果觉得我的内容还不错的话,可以关注下我在 segmentfault.com 上的直播。我主要从事 PHP 和 Java 方面的开发,《深入 PHP 内核》作者之一。

[视频直播] PHP 进阶之路 - 亿级 pv 网站架构的技术细节与套路 直播中我将毫无保留的分享我这六年的全部工作经验和踩坑的故事,以及会穿插着一些面试中的 考点难点加分点

评论列表

回复 吕滔 2018-02-02 15:12:22
咧,超喜欢你的博客模板怎么办。。。
回复 周梦康 2018-02-02 16:28:33
回复吕滔: 能得到老铁的欣赏,是我的荣幸。老铁复制就行。我都是东拼西凑。
回复 吕滔 2018-02-05 09:55:38
回复周梦康: 我觉得我不会客气了.
回复 周梦康 2018-02-05 10:34:19
回复吕滔: 哈哈哈,周末把评论修改了下,之前是邮箱提醒,现在换成微博登录之后,不知道怎么搞提醒好了,如果微博有这样的接口最好。如果没有只能考虑桌面消息推送试试。
回复 编辑之美 2018-03-17 13:34:36
你好,我实在Windows环境下,安装了nginx,然后测试一看,发现点击列表页和内容页时,会跳转到源站点,这是为什么呢?