2016年6月

补一篇文章,攒了好几篇想写的内容,今天先补一篇,然后慢慢补

单元测试这种东西大家都很熟悉了,它可以很方便的帮助你进行自检,增加代码的稳定性,同时可以帮助我们完成持续集成。mocha 大家也比较熟悉了,这里也不说了

先说一下 istanbul 这货吧,没错,就是伊斯坦布尔,其实就是一个检测代码覆盖率的一个工具,然后 Github 长这样儿 istanbul

这货可以帮你检测你各个地方的 js 代码,服务端、浏览器端都可以,也可以生成多种格式的检测报告。好吧,我知道你们对这个不感兴趣,那就直接来试试喽~

npm install -g istanbul

安装完成后,我们就可以去我们的代码目录试一下啦~

istanbul cover test.js

如果你在使用 mocha 也可以这样:

istanbul cover mocha

然后你就会发现,你的文件夹下出现了一个 coverage 的文件夹。对了!这就是我们的检测报告~

报告里会标注你的测试覆盖率以及那些代码没有被覆盖到,是不是感觉一下子就清楚了要完善什么了呢,哈哈哈哈哈

然后有小伙伴会问,那么,如果我想给 mocha 设置参数怎么办? 因为根据我们的常识可以知道,命令后面的空格分隔的参数是会传给这个命令的,也就是说如果我们直接在后面这样跟参数:

istanbul cover mocha --reporter spec

后面的参数是会传递给 istanbul 而不会传递给 mocha,那么我们该怎么办呢?

很简单,只要加上一个 -- 就好了~

istanbul cover mocha -- --reporter spec

istanbul 会把 -- 后面的参数传递给 mocha,这样就可以啦~

等等,话说你叨叨了这么大半天,不是说好测试 Babel 应用的么?怎么连一句话都没有提到?

好吧,下面就聊一下测试 Babel 的坑,首先是 mocha 测试 Babel 应用,这个很简单,Babel 官网就直接有文档,就先不说了,地址在这里 Babel + Mocha

然后就是 istanbul 加进来的时候你就会发现,特喵的根本不行!

是的,没办法,因为它现在还不支持 Babel 的检测,不过还好,istanbul 已经在做这方面的工作了,所以我们可以用它的测试版来完成我们的覆盖率检测~

npm install -g [email protected]

alpha.2 了,感觉离正式版也不太远了~

然后你就可以愉快的和 Babel 玩耍了~ ( 切~ 感觉好失望~

好吧,其实就是这样。 那么如果我想要再好玩一点儿,我们想在 travis 帮我们做持续集成的时候,顺便我我的检测报告发送到我的 codecov 上面去,我该怎么办呢?

嘿嘿~ follow me ~

travis.yml

...

before_script:
    - npm install [email protected]

script:
    - node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- --compilers js:babel-register --require babel-polyfill

after_success:
    - npm install codecov
    - ./node_modules/.bin/codecov

嗯嗯,就是这样喽,很简单吧~

为了美好的(gai)明(xu)天(qiu),快去把你的代码加上测试吧~

晚安喽~

好吧,一如既往的短篇记录性文章,记下坑供查阅

原因大概是这样的,公司有很多内网的服务系统,同属于同一个主域,但是是不同的子域,然后呢,当在一个系统需要调用另一个系统的时候,就会出现跨域的问题。所以呢,我们打算写一个通用代理程序来做中转,然后呢,先简单贴一下代码吧

var server = http.createServer(function(request, response) {
    ...

    var options = {
        hostname: address.hostname,
        port: address.port || 80,
        path: address.path,
        method: request.method,
        headers: request.headers,
    };

    options.headers.host = address.host;

    var proxy = http.request(options, function(res) {

        for(var key in res.headers) {
            response.setHeader(key, res.headers[key]);
        }

        response.setHeader("Access-Control-Allow-Origin", "*");

        res.pipe(response);
    });

    request.pipe(proxy);
});

嗯嗯,大概就是这样的

但是,马上我们就发现了问题,是的,事情总不会这么顺利。接下来我们发现,因为这个代理 Server 和 web 也不是同一个子域,所以虽然我们添加了允许跨域的头,但是会发现,发送到后端的 POST 跨域请求并没有携带 cookie 信息,然后也就没有办法得到另一个服务系统的认证。

OK,当我们手动在 ajax 请求中把 cookie 添加到头信息中的时候,像下面这样

$.ajax({
    ...
    headers: {"Cookie": document.cookie},
    ...
});

但是浏览器会提示这是一个不安全的操作,然后就。。。。 华丽丽的拒绝掉了

然后我们试着用 withCredentials 带上 cookie,大概是这个样子

$.ajax({
    ...
    xhrFields: {
        withCredentials: true
    }
});

然后呢,我们需要在我们的 Server 返回的时候加上一条头信息

response.setHeader("Access-Control-Allow-Credentials", true);

然后,是的,你会发现浏览器又给你报了一条错误,提示你 Access-Control-Allow-Origin 不能用 * 通配符。

听起来好像很合理,如果你想用一个域的 cookie 来认证的话,就指定一下这个域,很合理的要求,那么,当我们的想写一个通用的代理程序,希望任何一个域名都可以通过它的 cookie 来认证它要代理的 API 接口时,要怎么办?

听上去好像不是一个合理的需求,当时貌似,还真的有办法,就是再返回的时候,把请求的域填写进头信息里,就是谁访问我,我允许谁,代码大概就是这样的

response.setHeader("Access-Control-Allow-Credentials", true);
response.setHeader("Access-Control-Allow-Origin", request.headers.origin);

嗯嗯,就是这样啦,虽然感觉最后并不是一个很正确的方式,但是也算是解决了我们奇葩的需求了

今天就先这样吧,拜拜~