JavaScript中的promise模式
Promise模式简单来说就是函数返回一个promise对象,这个promise对象可能有三种状态:未完成、 已完成、 已拒绝。 对于传统的回调函数写法来说:
funcion test(){
do_something();
do_something();
getData(data, function(err, data){
if (err){
error_handle();
}
else{
success_handle();
}
})
}
错误处理和成功处理都是在回调中进行,在逻辑复杂的情况下极易形成回调嵌套。而对于promise模式来说则是这样(这里以promise库Q为例):
var Q = require('q');
function test(){
var deferred = Q.defer();
do_something();
getData(data, function(err, data){
if(err){
deferred.reject();
}
else{
deferred.resolve()
}
})
return deferred.promise
}
test.then(success_handle, error_handle)
CORS问题
CORS全称Cross-Origin resource sharing, 即:跨域资源共享 对于简单请求, 在服务端设置如下响应头:
Access-Control-Allow-Origin: *
这样就可以完成简单的跨域请求
如果浏览器请求不被认为是一个simple header,比如你要自定义一个头信息, 这个请求会被认为是一个preflight request
. 这时发送请求时header中会带有如下的信息:
Request Method:OPTIONS
Access-Control-Request-Headers:accept, params-token, content-type
Access-Control-Request-Method:POST
服务器需要设置返回头:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
服务器会根据request提交的header进行检查,如果检查没通过,就抛出错误,检查通过,则会将结果进行缓存,并会在responds的header中附带上这些信息,告诉浏览器可以进行通信。然后浏览器再发送真正的http请求。
也就是说,服务器和浏览器的第一次通信会出现两次http请求。第一次用于双方的确认,确认通过后,结果会被缓存,在缓存过期前就无需重复确认了。
参考文章:
Preflighted Requests
用Go实现CORS跨域资源共享的服务器支持
nginx代理的问题
在部署时发现的问题:req.headers.host得到的并不是域名,而是127.0.0.1:3000, 经过查阅发现是Nginx配置的问题,需要配置如下两行:
proxy_set_header Host $http_host;
proxy_set_header X-Forward-For $remote_addr;
proxy_set_header 用于覆盖或新增request的header,如果不配置上面两行,那么后台程序会认为通信来自:
nginx <=> server
那么得到的客户端ip就是nginx的ip,得到的host是后台服务的host。如果后台服务配置了访问限制,那么显然会把nginx给限制掉,配置了这两行后,后台才能得到正确的信息:
client <=> nginx
这里的$http_host
和$remote_addr
都是nginx的导出变量,可以在配置文件中直接使用。如果Host请求头部没有出现在请求头中,则$http_host
值为空,但是$host
值为主域名。因此,一般而言,会用$host
代替$http_host
变量,从而避免http请求中丢失Host头部的情况下Host不被重写的失误。
工具总结
"restify": "~2.6.1",
"request": ">=2.0.0",
"mongoose": "~3.8.7",
"redis": "x",
"async": "~0.2.10",
"q": "~1.0.0",
"log4js": "~0.6.10",
"moment": "x",
"connect": "x",
"lodash": "~2.4.1",
"winston": "~0.7.2",
"winston-mongodb": "~0.4.3",
"sanitize-html": "x"