月度归档:2011年11月

研究Ajax请求受登录保护的URL的优雅解决

在此先记下思路。

场景:登录页面login,在一个登录后才能访问的页面dashboard,dashboard上有一个按钮button,button绑定了一个单击事件,触发后发出一个ajax请求,ajax请求返回一个html片段,并把这个html片段更新到某个dom标签。

条件:dashboard页面如果登录过期,再次访问dashboard或点击button发出ajax请求应该跳转到登录页面login。

问题: 如果对ajax熟悉或有以上类似情况经验的,应该知道,登录过期后,如果不刷新dashboard页面,而直接点击button发出ajax请求,那么ajax获取到的响应内容会是整个登录页面login,而不是正确的那个html片段,这样更新到dom标签的话,页面整个乱掉了。

解决:ajax请求的地址在响应内容前先做登录判断,如过期则返回一个标志位,比如login=false\true,在ajax回调的方法中判断此标志位, 如果login=true,则location.href=登陆页面url。

优雅:理论上是这样,还没试验。拿javaEE应用+jQuery Ajax(版本1.5+)来说。因为我比较熟悉JEE。JEE可以通过过滤器Filter来控制所有的受登录保护的url请求。

jQuery Ajax可以通过ajaxSetup设置全局选项,其中有一项是关于响应的状态码的,在1.5+版本中叫 statusCode ,而且jQuery Ajax有一个请求头:X-Requested-With = XMLHttpRequest

没错了,通过状态码及请求头就可以更方便,更自动的解决登录保护问题。
做法为: Filter通过request.getHeader(“X-Requested-With”)可以判断是否为Ajax请求(所以自己写的ajax最好也加上这个请求头)。 当是Ajax请求并且登录已经过期,则直接在Filter中响应一个状态码401,或者其他自定义各种码。在ajaxSetup全局选项中配置如何处理这个状态码,亦即location.href=登陆页面url。这样就可以统一自动的处理各种登录保护下的ajax请求了。

ajaxSetup例子如下:

$.ajaxSetup({
  statusCode: {
    '401': function() {
      //alert('登录超时了哦...');
      //如果做了登录自动跳回,可以再加个东东
      var currUrl = encodeURIComponent(location.href);
      location.href = '/login?url=' + currUrl;
    }
  }
});

/* URI编码及解码方法 */
/* 推荐方式 */
console.info(encodeURIComponent('http://www.aa.com/hh ll/'));
console.info(decodeURIComponent('http://www.aa.com/hh ll/'));
/* 另外的简单方式
encodeURI 不对下列字符进行编码:“:”、“/”、“;”和“?”。请使用 encodeURIComponent 对这些字符进行编码
 */
console.info(encodeURI('http://www.aa.com/hh ll/'));
console.info(decodeURI('http://www.aa.com/hh ll/'));

apache反向代理配置一例

配置apache虚拟主机一例,使用了反向代理:

<VirtualHost *:80>
        ServerAdmin cc@cssor.com
        ServerName cssor.com
        ServerAlias  www.cssor.com
        DocumentRoot /home/www/cssor.com/WebRoot
        <Directory /home/www/cssor.com/WebRoot>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                Allow from all
        </Directory>

        ProxyPreserveHost On
        ProxyRequests Off
        #排除不需要后端应用处理的目录,由apache接管
        #一般用来排除掉静态文件
        #这里访问 http://cssor.com/res/img/aa.png直接由apache处理
        ProxyPass /res/ !

        ProxyPass / http://localhost:8080/
        #ProxyPassReverse用于隐藏后端域名
        #这里localhost就不会显示到浏览器地址栏,保持域名cssor.com
        ProxyPassReverse / http://localhost:8080/

        ErrorLog /var/log/apache2/cssor.com.log
        CustomLog /var/log/apache2/cssor.com.custom.log common
</VirtualHost>

Eclipse自动编译带来的SVN版本控制问题

项目中,SVN通过每个文件夹下隐藏的.svn文件夹来进行版本控制。

Eclipse的源码文件夹src自然需要svn控制,而eclipse开启自动编译的话,默认src下的所以文件及文件夹都会被编译到classes文件夹中去,这时候.svn文件夹也被copy到了classes文件夹中。

而这个.svn文件夹保存的是src版本信息而非classes版本信息,.svn被克隆了, 在classes进行svn提交发现提示所有的.java源码missing,如果提交了,相当于在src删除了所有的源码文件。

这个缺陷对不知道情况的人会比较严重。解决方法就是修改eclipse的build path,排除掉.svn文件夹的自动编译。

右键项目名 -> 选择Build Path,选择Configure Build Path -> 选择Source,找到该项目下的Excluded项,编辑,添加排除规则: **/.svn/**

最后保存即可。

找图看这里: http://www.360doc.com/content/11/0729/12/2631212_136507208.shtml

 

Nginx Location配置总结及基础最佳实践

参考来源: http://blog.zol.com.cn/1067/article_1066186.html,http://flandycheng.blog.51cto.com/855176/280121

语法规则: location [=|~|~*|^~] /uri/ { … }

= 开头表示精确匹配

^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。

~ 开头表示区分大小写的正则匹配

~*  开头表示不区分大小写的正则匹配

!~和!~*分别为区分大小写不匹配及不区分大小写不匹配 的正则

/ 通用匹配,任何请求都会匹配到。

多个location配置的情况下匹配顺序为(参考资料而来,还未实际验证,试试就知道了,不必拘泥,仅供参考):

首先匹配 =,其次匹配^~, 其次是按文件中顺序的正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。

例子,有如下匹配规则:

location = / {
   #规则A
}
location = /login {
   #规则B
}
location ^~ /static/ {
   #规则C
}
location ~ \.(gif|jpg|png|js|css)$ {
   #规则D
}
location ~* \.png$ {
   #规则E
}
location !~ \.xhtml$ {
   #规则F
}
location !~* \.xhtml$ {
   #规则G
}
location / {
   #规则H
}

那么产生的效果如下:

访问根目录/, 比如http://localhost/ 将匹配规则A

访问 http://localhost/login 将匹配规则B,http://localhost/register 则匹配规则H

访问 http://localhost/static/a.html 将匹配规则C

访问 http://localhost/a.gif, http://localhost/b.jpg 将匹配规则D和规则E,但是规则D顺序优先,规则E不起作用, 而 http://localhost/static/c.png 则优先匹配到 规则C

访问 http://localhost/a.PNG 则匹配规则E, 而不会匹配规则D,因为规则E不区分大小写。

访问 http://localhost/a.xhtml 不会匹配规则F和规则G,http://localhost/a.XHTML不会匹配规则G,因为不区分大小写。规则F,规则G属于排除法,符合匹配规则但是不会匹配到,所以想想看实际应用中哪里会用到。

访问 http://localhost/category/id/1111 则最终匹配到规则H,因为以上规则都不匹配,这个时候应该是nginx转发请求给后端应用服务器,比如FastCGI(php),tomcat(jsp),nginx作为方向代理服务器存在。

所以实际使用中,个人觉得至少有三个匹配规则定义,如下:
#直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
#这里是直接转发给后端应用服务器了,也可以是一个静态首页
# 第一个必选规则
location = / {
    proxy_pass http://tomcat:8080/index
}

# 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
# 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
    root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
    root /webroot/res/;
}

#第三个规则就是通用规则,用来转发动态请求到后端应用服务器
#非静态文件请求就默认是动态请求,自己根据实际把握
#毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了
location / {
    proxy_pass http://tomcat:8080/
}

对于以上基础推荐配置,有一个补充,就是关于转发有一点需要注意。例如下面配置,对一个目录转发:

location ^~ /outer/ {
    #case A: url最后以/结尾
    proxy_pass http://tomcat:8080/
    #case B: url最后没有/
    #proxy_pass http://tomcat:8080  
}

关键在于最后的/,访问localhost/outer/in.html,其中case A 会转发到tomcat:8080/in.html, 而case B 会转发到 tomcat:8080/outer/in.html,所以务必注意了。

未试验过的其他信息:

三、ReWrite语法
last – 基本上都用这个Flag。
break – 中止Rewirte,不在继续匹配
redirect – 返回临时重定向的HTTP状态302
permanent – 返回永久重定向的HTTP状态301
1、下面是可以用来判断的表达式:
-f和!-f用来判断是否存在文件
-d和!-d用来判断是否存在目录
-e和!-e用来判断是否存在文件或目录
-x和!-x用来判断文件是否可执行
2、下面是可以用作判断的全局变量
例:http://localhost:88/test1/test2/test.php
$host:localhost
$server_port:88
$request_uri:http://localhost:88/test1/test2/test.php
$document_uri:/test1/test2/test.php
$document_root:D:\nginx/html
$request_filename:D:\nginx/html/test1/test2/test.php
四、Redirect语法
server {
listen 80;
server_name start.igrow.cn;
index index.html index.php;
root html;
if ($http_host !~ “^star\.igrow\.cn$&quot {
rewrite ^(.*) http://star.igrow.cn$1 redirect;
}
}
五、防盗链location ~* \.(gif|jpg|swf)$ {
valid_referers none blocked start.igrow.cn sta.igrow.cn;
if ($invalid_referer) {
rewrite ^/ http://$host/logo.png;
}
}
六、根据文件类型设置过期时间
location ~* \.(js|css|jpg|jpeg|gif|png|swf)$ {
if (-f $request_filename) {
expires 1h;
break;
}
}
七、禁止访问某个目录
location ~* \.(txt|doc)${
root /data/www/wwwroot/linuxtone/test;
deny all;
}

 

++ 一些可用的全局变量
$args
$content_length
$content_type
$document_root
$document_uri
$host
$http_user_agent
$http_cookie
$limit_rate
$request_body_file
$request_method
$remote_addr
$remote_port
$remote_user
$request_filename
$request_uri
$query_string
$scheme
$server_protocol
$server_addr
$server_name
$server_port
$uri

ubuntu管理用到的命令

1、查看磁盘空间 (http://hi.baidu.com/tlexander/blog/item/0e5fdb971167a47c55fb969a.html)

df -hl #查看磁盘剩余空间
df -h  #查看每个根路径的分区大小
du -sh #[目录名] 返回该目录的大小
du -sm #[文件夹] 返回该文件夹总M数

2、ubuntu查看进程端口号及运行的程序 (http://guotieyun.blog.163.com/blog/static/10702102920104921610449/)

netstat -atunp | more
#根据端口号查pid,比如知道80,查apache是否运行中
lsof -i:631

3、为网卡配置静态IP地址 (http://hi.baidu.com/beloving/blog/item/9eff51437411fc149213c6d4.html)

sudo vi /etc/network/interfaces,并用下面的行来替换有关eth0的行:

# The primary network interface
auto eth0
iface eth0 inet static
address 192.168.3.90
gateway 192.168.3.1
netmask 255.255.255.0
#network 192.168.3.0
#broadcast 192.168.3.255
用下面的命令使网络设置生效:
sudo /etc/init.d/networking restart

4、管理软件,除了apt-get,还可以aptitude

aptitude update	        #更新可用的包列表
aptitude upgrade	#升级可用的包
aptitude dist-upgrade	#将系统升级到新的发行版
aptitude install pkgname	#安装包
aptitude remove pkgname	#删除包
aptitude purge pkgname	#删除包及其配置文件
aptitude search string	#搜索包
aptitude show pkgname	3显示包的详细信息
aptitude clean	        #删除下载的包文件
aptitude autoclean	#仅删除过期的包文件

5、设置主机名称(hostname)

sudo /bin/hostname #查看当前主机的主机名称
sudo /bin/hostname newname  #设置当前主机的主机名称

6、

ubuntu禁止apache开机自启动

简单方便而优雅,几个命令搞定(来自 http://emilientaque.fr/2010/01/how-to-disable-apache2-from-running-on-startup/):

# 移除apache2自启动脚本,
# 参数-f是为了解决 update-rc.d: /etc/init.d/apache2 exists during rc.d purge的问题
sudo update-rc.d -f apache2 remove

# 同时也可以方便的恢复自启动脚本
sudo update-rc.d apache2 defaults

# 或者编辑文件 /etc/default/apache2 设置内容中的 NO_BOOT 值为 1.

nginx and tomcat7 in ubuntu 10.04

系统为ubuntu 10.04,选用nginx+tomcat7搭建jsp运行环境,nginx处理静态文件,其余动态请求则转发给tomcat7。

首先安装 nginx,我先用的如下命令(参考http://wiki.ubuntu.org.cn/Nginx):

sudo apt-get install nginx

结果安装的nginx版本相当低:

:~$ nginx -V
nginx: nginx version: nginx/0.7.64

后来在官方看到了官方提供的软件源,虽然很纳闷为什么只提供了ubuntu10.04的源,而没有其他版本的源,倒是也刚好符合当前系统版本。

官方下载地址:http://nginx.org/en/download.html

使用官方源安装更新如下:

sudo vi /etc/apt/sources.list
#加入如下内容
deb http://nginx.org/packages/ubuntu/ lucid nginx
deb-src http://nginx.org/packages/ubuntu/ lucid nginx

#然后执行下面的命令即可
sudo apt-get update
sudo apt-get install nginx  (或者命令: aptitude install nginx)

这样nginx就会安装或更新到最新的稳定版本,当前我的是 nginx 1.0.8。

Ubuntu安装之后的文件结构大致为:
所有的配置文件都在/etc/nginx下,并且每个虚拟主机已经安排在了/etc/nginx/sites-available下
程序文件在/usr/sbin/nginx
日志放在了/var/log/nginx中
并已经在/etc/init.d/下创建了启动脚本nginx
默认的虚拟主机的目录设置在了/var/www/nginx-default (有的版本 默认的虚拟主机的目录设置在了/var/www, 请参考/etc/nginx/sites-available里的配置)

以上皆参考http://wiki.ubuntu.org.cn/Nginx

管理nginx启动,停止使用如下命令:

sudo /etc/init.d/nginx start
sudo /etc/init.d/nginx stop
sudo /etc/init.d/nginx restart

启动后,访问ip地址,端口默认是80,就可以看到 Welcome to nginx!,这样就表明成功了。

安装tomcat7请参考这里: http://www.cssor.com/virtualbox-install-ubuntu-server-10-04-jdk6-apache2-tomcat7.html

接下来是配置nginx,确保动态请求转发给tomcat。

值得一提的是,用官方源安装的nginx已经没有sites-available,sites-enable这两个文件夹了。

所以虚拟主机 应该配置到/etc/nginx/conf.d 目录下。

直接 cp default.conf  new-host.conf,然后配置new-host.conf即可。

在new-host.conf中主要配置如下:

server {
    listen       80;
    server_name  new-host.example;
    access_log  /var/log/nginx/new-host.example.access.log  main;

    #当其他location无匹配时,默认都转发到tomcat去处理
    #网上有些配置是根据后缀.jsp匹配的,实际应用中很傻
    #尤其是REST的uri风格,后缀无关紧要,动态请求完全可以映射为无后缀uri
    location / {
        proxy_connect_timeout 3;
        proxy_send_timeout 30;
        proxy_read_timeout 30;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://new-host.example:8080;
    }
    #将静态文件交给nginx处理而不必转发给tomcat
    #按后缀正则匹配优先级比 / 高,所以放后面也没关系
    location ~ \.(gif|jpg|jpeg|png|css|js)$ {
        root   /home/WebRoot;
        expires 100d;
    }

    #...................其他配置项目略
}

nginx转发规则配置好,然后用new-host.example的域名配置好tomcat的虚拟主机(编辑server.xml):

<Host name="new-host.example" appBase="/home" uppackWARs="true" autoDeploy="false">
    <Context docBase="WebRoot" path="" reloadable="true" />
</Host>

最后重启nginx,与tomcat:

sudo /etc/init.d/tomcat7 restart
sudo /etc/init.d/nginx restart