07月28, 2016

fis3与nginx的故事

我知道现在有很多的构建工具,如grunt、gulp、webpack,还有rollup,据说是要干掉webpack来着。

每个人都有自己钟爱的构建工具,反正我个人觉得FIS3还是相当不错。

在FIS3中,我们可以使用server.conf来rewrite地址,但是无法解决代理的问题。(在新版本中已经实现,后面会提到)

那么唯一的方式只能通过nginx来做实现了。

nginx的一个报错

下午在启动nginx的时候,不知道被我咋整的,出现了如下的ERROR报错信息:

nginx: [emerg] open() "/usr/local/var/run/nginx.pid" failed (2: No such file...

查了一下百度和谷歌,都说用nginx -c 配置文件的路径来启动就好了。然后我在那边,倒腾了近一个多小时,还是不行,急得我都想把mac给砸了。然后我问了一下群里面的人,有个人说了一句:

你都没有启动nginx,哪来的pid呢?

真是一语惊醒梦中人啊,赶紧把上面路径中的nginx.pid给删除了,然后再启动就OK了。

nginx配置代理

server {
        listen       80;
        server_name  www.zgz.com;
        location / {
            proxy_pass   http://127.0.0.1:8080;
            proxy_redirect              off;
            proxy_set_header            Host $host;
            proxy_set_header            X-Real-IP $remote_addr;
            proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;
        }  

        location ~ /java-web/ {
            proxy_pass       http://127.0.0.1:18001;
            proxy_set_header            Host $host;
            proxy_set_header            X-Real-IP $remote_addr;
            proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;
        }

    }

简单解释一下,首先是有一个域名:www.zgz.com(不要忘记在host里面配置,只需要127.0.0.1与它对应即可),当访问它的时候,让跳 http://127.0.0.1:8080,即FIS项目的访问路径。

当我在项目中向服务端发起请求时,假设路径是这样的:

/java-web/xxx/xx

那么上面的nginx就会拦截到java-web的路径,将其转发到http://127.0.0.1:18001,然后路径就会变成:

http://127.0.0.1:18001/java-web/xxx/xx

至于这三行:

proxy_set_header            Host $host;
proxy_set_header            X-Real-IP $remote_addr;
proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;

nginx为了实现反向代理的需求而增加了一个ngx_http_proxy_module模块。其中proxy_set_header指令就是该模块需要读取的配置文件。在这里,所有设置的值的含义和http请求同中的含义完全相同,除了Host外还有X-Forward-For。

Host的含义是表明请求的主机名,因为nginx作为反向代理使用,而如果后端真是的服务器设置有类似防盗链或者根据http请求头中的host字段来进行路由或判断功能的话,如果反向代理层的nginx不重写请求头中的host字段,将会导致请求失败【默认反向代理服务器会向后端真实服务器发送请求,并且请求头中的host字段应为proxy_pass指令设置的服务器】。

同理,X_Forward_For字段表示该条http请求是有谁发起的?如果反向代理服务器不重写该请求头的话,那么后端真实服务器在处理时会认为所有的请求都来在反向代理服务器,如果后端有防攻击策略的话,那么机器就被封掉了。因此,在配置用作反向代理的nginx中一般会增加两条配置,修改http的请求头: proxy_set_header Host $http_host; proxy_set_header X-Forward-For $remote_addr; 这里的$http_host和$remote_addr都是nginx的导出变量,可以再配置文件中直接使用。如果Host请求头部没有出现在请求头中,则$http_host值为空,但是$host值为主域名。因此,一般而言,会用$host代替$http_host变量,从而避免http请求中丢失Host头部的情况下Host不被重写的失误。

对于我们来说,只要拷贝这三条规则就可。

注:http://127.0.0.1:18001,这个地址是我在做测试时,本地开了一个端口号为18001的express的项目,只需要简单地建立一个public目录,里面有一个文件,能够映射到即可。

FIS3的server.conf

FIS3文档之FIS3的假数据模拟

老实说文档已经很详细了,那么我说说我在项目中的实施吧。

  • json方式的处理

首先我这边的请求路径都是类似这样的:

/java-web/A/B/queryAll

那么我们在写mock的时候,可以简单把mock文件起名叫queryAll.json或者queryAll.js。然后在server.conf中,可以简单写下这样一条规则(mock数据都放在mock文件夹下):

rewrite ^\//java-web/(/.*)?/(.*?)$ /mock/$2.json

中间可能会有1个或者多个的/xxx这样的路径,$2是表示匹配第二个括号,即结尾的名称。

当然了,这个大前提是所有的URL都必须是这样的规则。

  • 动态数据的数据

FIS3提供了动态数据的处理,它对应的js文件是类似这样书写的:

module.exports = function(req, res, next) {


    /*
    res.write("Hello world ");

    // set custom header.
    // res.setHeader("xxxx", "xxx");

    res.end("The time is " + Date.now());
    */

    var json = {
        a: 1,
        b: 3
    }


    res.json(json);

    res.end()

};

它内置了express,所以res的方法可以用express的方法。

express内置的实现

  • 支持简单的代理

如官方的例子所示:

proxy ^\/api\/test http://127.0.0.1:9119/api/test

感觉有了它,似乎不怎么需要nginx了。。

经测试,post请求data,似乎有问题,已经提了issue,get是没有问题的。

注意,不要把proxy写成rewrite,一开始我傻B了,然后发现一直不对,还以为这个功能没有实现呢,囧。。

结语

总的来说,FIS3给我的感觉还是不错的。之前的版本因为编译速度慢,导致在跟其他同事推广的时候,被诟病。但新的版本来说,它的编译速度提升了很多。

PS:新项目用的是angularjs的框架,一开始是打算套在客户端的,但现在又说要放在网页上。好在暂时说服了,说等未来如果用户群体庞大了,希望在IE8什么的进行访问,再做重构了。说真的,习惯了数据驱动页面之后,就不是太想用jQuery了,也许到那时候会考虑使用avalon2吧。

本文链接:www.my-fe.pub/post/fis3-and-nginx.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。