天天看点

Nginx安全加固配置手册 第1章   概述 第2章    产品介绍 第3章   Nginx的安全加固配置

Nginx(发音同engine x)是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,由俄罗斯的程序设计师Igor Sysoev所开发,可以稳定地运行在Linux、Windows等操作系统上,其特点是占用内存少,并发能力强。

同其他软件一样,Nginx也出现过一些安全漏洞,利用这些漏洞可以对Web服务器进行渗透攻击。本文主要描述互联网架构中常用产品Nginx 的配置和安全加固工作,最终用以指导系统实施。

本文档用于指导系统工程师进行系统实施工作,架构师和系统工程师应该通读本文档,选择适当方式用于自己的系统。

查看当前系统中部署的Nginx版本。

<code>[root@localhostnginx]</code><code># nginx -v</code>

<code>nginxversion: nginx</code><code>/1</code><code>.2.5</code>

确保nginx.conf配置文件上禁用autoindex模块,即没有autoindex的配置。

加固检查:

确保nginx.conf配置文件上禁用autoindex,即autoindex off或者没有配置autoindex。

如果开启的话(默认情况下)所有的错误页面都会显示服务器的版本和信息。nginx.conf配置如下:

<code>http{</code>

<code>    </code><code>include       naxsi_core.rules;</code>

<code>    </code><code>include      mime.types;</code>

<code>    </code><code>default_type  application</code><code>/octet-stream</code><code>;</code>

<code>    </code><code>sendfile        on;</code>

<code>    </code><code>server_tokens off;</code>

<code>    </code><code>... ...</code>

<code>[root@localhost~]</code><code># curl -I http://localhost/wavsep</code>

<code>HTTP</code><code>/1</code><code>.1301 Moved Permanently</code>

<code>Server:nginx</code>

<code>Date:Tue, 31 Dec 2013 23:20:29 GMT</code>

<code>Content-Type:text</code><code>/html</code>

<code>Content-Length:178</code>

<code>Location:http:</code><code>//localhost/wavsep/</code>

<code>Connection:keep-alive</code>

<code>Keep-Alive:timeout=30</code>

设置自定义缓存以限制缓冲区溢出攻击。nginx.conf配置如下:

<code>    </code><code>server{</code>

<code>        </code><code>... ...</code>

<code>        </code><code>client_body_buffer_size  16K;</code>

<code>       </code><code>client_header_buffer_size  1k;</code>

<code>        </code><code>client_max_body_size  1m;</code>

<code>       </code><code>large_client_header_buffers  4  8k;</code>

     注:上述的参数不是最优参数,仅供参考。

     确保server模块中配置了上述标红的配置。

设置timeout设低来防御DOS攻击,nginx.conf配置如下:

<code>http {</code>

<code>       </code><code>client_body_timeout   10;</code>

<code>       </code><code>client_header_timeout  30;</code>

<code>       </code><code>keepalive_timeout     30  30;</code>

<code>       </code><code>send_timeout          10;</code>

鉴于日志的输出格式还未确定,目前暂时先使用Nginx默认的日志格式。nginx.conf配置如下:

http {

    ......

    log_format  main  '$remote_addr - $remote_user [$time_local]"$request" ''$status $body_bytes_sent "$http_referer"''"$http_user_agent" "$http_x_forwarded_for"';

    access_log logs/ access.log  main;

    ... ...

     查看Nginx的日志文件是否存在,并且访问应用时,有日志输出。

[root@srv-dfh526~]# tail -3f /usr/local/nginx/logs/dfh.smartcity.com.log

Client_IP:10.5.220.27  Client_IP_For:- - - [10/Jan/2014:10:42:20+0800] "method:GET /portal/images/service_6.jpg HTTP/1.1"Protocol:"http" Status:304 Size:0"http://dfh.smartcity.com/portal/ext/index/index.jsp"  Args:- Browser:"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1;Trident/5.0; BOIE9;ZHCN)"

Client_IP:10.1.108.133  Client_IP_For:- - - [10/Jan/2014:10:42:23+0800] "method:GET/search/search?collId=1,2,3,4,5,6&amp;query=%B3%C7%CA%D0%B9%E3%B2%A5HTTP/1.1" Protocol:"http" Status:200 Size:4145"http://dfh.smartcity.com/search/search?collId=1,2,3,4,5,6&amp;query=%E5%9F%8E%E5%B8%82%E5%B9%BF%E6%92%AD&amp;appID=1&amp;ucode=utf-8"  Args:- Browser:"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/30.0.1599.101 Safari/537.36"

Client_IP:10.5.220.27  Client_IP_For:- - - [10/Jan/2014:10:42:24+0800] "method:GET /portal/images/change/service1_1.png HTTP/1.1"Protocol:"http" Status:304 Size:0"http://dfh.smartcity.com/portal/ext/index/index.jsp"  Args:- Browser:"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1;Trident/5.0; BOIE9;ZHCN)"

注:日志输出格式需要看配置的情况。

在目前的应用系统中值使用到POST和GET方法,所以除了它们之外,其他方式的请求均可拒绝。Nginx.conf配置如下:

<code>server{</code>

<code>       </code><code>... ...</code>

<code>       </code><code>if</code><code>($request_method !~ ^(GET|HEAD|POST)$) {        </code>

<code>                     </code><code>return404;</code>

<code>              </code><code>}</code>

     注:因为目前统一错误应用没有定版,所以先使用404,实际中应该使用444.

使用火狐浏览器的poster插件:

<a href="http://s3.51cto.com/wyfs02/M01/59/3A/wKioL1TMOKXQUZjMAAIlx1GgLrY988.jpg" target="_blank"></a>

尝试使用不同的请求方式试试,能不能访问。

Nginx日志主要用于日后的审计和分析,对系统的安全有着重要的意义。但是随着时间的推移,日志文件会变得越来越大,这就需要对日志进行处理分割了。

第一步:建立脚本文件:

<code>[root@localhosthome]</code><code># vim nginx_log.sh</code>

<code>#/bin/bash</code>

#日志将要存放的路径

<code>savepath_log=</code><code>'/logs/nginx/logs'</code>

#nginx的日志路径

<code>nglogs=</code><code>'/usr/logs'</code>

<code> </code> 

<code>mkdir</code><code>-p $savepath_log/$(</code><code>date</code> <code>+%Y)/$(</code><code>date</code> <code>+%m)</code>

<code>mv</code><code>$nglogs</code><code>/centoshost</code><code>.com.log $savepath_log/$(</code><code>date</code> <code>+%Y)/$(</code><code>date</code><code>+%m)</code><code>/centoshost</code><code>$(</code><code>date</code> <code>+%Y%m%d%H%M).log</code>

<code>mv</code><code>$nglogs</code><code>/wavsep</code><code>.com.log $savepath_log/$(</code><code>date</code> <code>+%Y)/$(</code><code>date</code> <code>+%m)</code><code>/wavsep</code><code>$(</code><code>date</code><code>+%Y%m%d%H%M).log</code>

<code>kill</code><code>-USR1 $(</code><code>cat</code> <code>/var/run/nginx/nginx</code><code>.pid)</code>

其中,savepath_log和nglogs分别表示日志分割后的存放目录和Nginx的日志目录,均需要根据实际情况修改;centoshost.com.log和wavsep.com.log为Nginx现在的文件文件名称,也需要根据实际情况修改;centoshost和wavsep表示切割后保存的日志文件名称,需要根据实际情况修改。

第二步:为nginx_log.sh分配可以执行权限

[root@localhost home]# chmod 755 nginx_log.sh

第三步:设定定时器

<code>[[email protected]]</code><code># crontab -e</code>

<code>0000 * * * </code><code>/home/nginx_log</code><code>.sh </code><code>#执行文件存放路径,每天凌晨00:00执行</code>

注:保存方式与vim一致,输入:wq。

第四部:重启定时器

<code>[[email protected]]</code><code># cd /etc/init.d</code>

<code>[[email protected]]</code><code># ./crond restart</code>

<code>停止 crond:                                    [确定]</code>

<code>正在启动 crond:                                [确定]</code>

过程图:

第一:Nginx日志切割前

第二:保存日志的目录(切割前)

第三:Nginx日志切割后

第四:保存日志的目录(切割后)

<a href="http://s3.51cto.com/wyfs02/M00/59/3A/wKioL1TMOSrSdRR8AACKipWmi8A288.jpg" target="_blank"></a>

模块 ngx_http_access_module 允许限制某些IP地址的客户端访问。

如下范例:

location/ {

    deny  192.168.1.1;

    allow 192.168.1.0/24;

    allow 10.1.1.0/16;

    allow 2001:0db8::/32;

    deny  all;

}

注:规则按照顺序依次检测,直到匹配到第一条规则。 在这个例子里,IPv4的网络中只有 10.1.1.0/16 和 192.168.1.0/24允许访问,但 192.168.1.1除外, 对于IPv6的网络,只有2001:0db8::/32允许访问。

Naxsi模块的集成,是基于Nginx已经部署了或已经存在系统中。

第一步:下载naxsi

<a href="http://s3.51cto.com/wyfs02/M02/59/3D/wKiom1TMOOeQ95Q7AAG2G5s1fxY163.jpg" target="_blank"></a>

注:如果不能上网可以事先下载,再上传到服务器中。

第二步:解压naxsi

[qiang@localhost install]$ tar -zxvfnaxsi-core-0.51-1.tgz

第三步:切换到naxsi-core-0.51-1目录,并复制其配置文件到nginx.conf同目录下

[qiang@localhostnaxsi_config]$ cp naxsi_core.rules /etc/nginx/naxsi_core.rules

修改naxsi_core.rules的配置如下:

##################################

## INTERNAL RULESIDS:1-999     ##

#@MainRule "msg:weirdrequest, unable to parse" id:1;

#@MainRule"msg:request too big, stored on disk and not parsed" id:2;

#@MainRule"msg:invalid hex encoding, null bytes" id:10;

#@MainRule"msg:unknown content-type" id:11;

#@MainRule"msg:invalid formatted url" id:12;

#@MainRule "msg:invalidPOST format" id:13;

#@MainRule"msg:invalid POST boundary" id:14;

## SQL InjectionsIDs:1000-1099 ##

MainRule"rx:select|union|update|delete|insert|table|from|ascii|hex|unhex|drop""msg:sql keywords" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie""s:$SQL:8" id:1000;

MainRule"str:\"" "msg:double quote""mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:8,$XSS:8"id:1001;

MainRule"str:0x" "msg:0x, possible hex encoding""mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:2" id:1002;

## Hardcore rules

MainRule"str:/*" "msg:mysql comment (/*)""mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:8" id:1003;

MainRule"str:*/" "msg:mysql comment (*/)""mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:8" id:1004;

MainRule "str:|""msg:mysql keyword (|)" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:8"id:1005;

##MainRule"str:&amp;&amp;" "msg:mysql keyword (&amp;&amp;)""mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:8" id:1006;

## end of hardcore rules

MainRule"str:--" "msg:mysql comment (--)""mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:4" id:1007;

MainRule "str:;""msg:; in stuff" "mz:BODY|URL|ARGS""s:$SQL:4,$XSS:8" id:1008;

MainRule "str:=""msg:equal in var, probable sql/xss" "mz:ARGS|BODY""s:$SQL:2" id:1009;

MainRule "str:(""msg:parenthesis, probable sql/xss""mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$SQL:4,$XSS:8"id:1010;

MainRule "str:)""msg:parenthesis, probable sql/xss""mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$SQL:4,$XSS:8"id:1011;

MainRule "str:'""msg:simple quote" "mz:ARGS|BODY|URL|$HEADERS_VAR:Cookie""s:$SQL:4,$XSS:8" id:1013;

MainRule "str:,""msg:, in stuff" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie""s:$SQL:4" id:1015;

MainRule "str:#""msg:mysql comment (#)""mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:4" id:1016;

###############################

## OBVIOUS RFIIDs:1100-1199 ##

MainRule"str:http://" "msg:http:// scheme""mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1100;

MainRule"str:https://" "msg:https:// scheme""mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1101;

MainRule"str:ftp://" "msg:ftp:// scheme""mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1102;

MainRule"str:php://" "msg:php:// scheme""mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1103;

MainRule"str:sftp://" "msg:sftp:// scheme""mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1104;

MainRule"str:zlib://" "msg:zlib:// scheme""mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1105;

MainRule"str:data://" "msg:data:// scheme" "mz:ARGS|BODY|$HEADERS_VAR:Cookie""s:$RFI:8" id:1106;

MainRule"str:glob://" "msg:glob:// scheme""mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1107;

MainRule"str:phar://" "msg:phar:// scheme""mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1108;

MainRule"str:file://" "msg:file:// scheme""mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1109;

#######################################

## Directory traversalIDs:1200-1299 ##

#######################################                                         

MainRule "str:..""msg:double dot" "mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie""s:$TRAVERSAL:4" id:1200;

MainRule"str:/etc/passwd" "msg:obvious probe""mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$TRAVERSAL:4"id:1202;

MainRule"str:c:\\" "msg:obvious windows path" "mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie""s:$TRAVERSAL:4" id:1203;

MainRule"str:cmd.exe" "msg:obvious probe""mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$TRAVERSAL:4"id:1204;

MainRule"str:\\" "msg:backslash""mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$TRAVERSAL:4"id:1205;

MainRule "str:/""msg:slash in args" "mz:ARGS|BODY|$HEADERS_VAR:Cookie""s:$TRAVERSAL:2" id:1206;

########################################

## Cross Site ScriptingIDs:1300-1399 ##

MainRule"str:&lt;" "msg:html open tag""mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$XSS:8" id:1302;

MainRule"str:&gt;" "msg:html close tag""mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$XSS:8" id:1303;

MainRule "str:[""msg:[, possible js" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie""s:$XSS:4" id:1310;

MainRule "str:]""msg:], possible js" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie""s:$XSS:4" id:1311;

MainRule "str:~""msg:~ character" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie""s:$XSS:4" id:1312;

MainRule"str:`"  "msg:grave accent!" "mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$XSS:8"id:1314;

MainRule "rx:%[2|3]."  "msg:double encoding !""mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$XSS:8" id:1315;

MainRule "rx:%3[c|e]."  "msg:double encoding !""mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$XSS:8" id:1316;

MainRule "rx:\\\u003[c|e]"  "msg:tag encoding !""mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$XSS:8" id:1317;

MainRule "str:&amp;#" "msg:utf7/8 encoding" "mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie""s:$EVADE:4" id:1318;

####################################

## Evading tricks IDs:1400-1500 ##

MainRule"str:&amp;#" "msg: utf7/8 encoding""mz:ARGS|BODY|URL|$HEADERS_VAR:Cookie" "s:$EVADE:4"id:1400;

MainRule"str:%U" "msg: M$ encoding""mz:ARGS|BODY|URL|$HEADERS_VAR:Cookie" "s:$EVADE:4"id:1401;

MainRule negative"rx:multipart/form-data|application/x-www-form-urlencoded""msg:Content is neither mulipart/x-www-form..""mz:$HEADERS_VAR:Content-type" "s:$EVADE:4" id:1402;

#############################

## File uploads: 1500-1600##

MainRule"rx:.ph|.asp|.ht" "msg:asp/php file upload!""mz:FILE_EXT" "s:$UPLOAD:8" id:1500;

MainRule "rx:.jsp""msg:asp/php file upload!" "mz:FILE_EXT""s:$UPLOAD:8" id:1501;

MainRule "rx:.html""msg:asp/php file upload!" "mz:FILE_EXT""s:$UPLOAD:8" id:1502;

MainRule "rx:.php""msg:asp/php file upload!" "mz:FILE_EXT""s:$UPLOAD:8" id:1503;注:(1)nginx.conf所有的目录是在nginx编译安装时,默认的配置是&lt;prefix&gt;/conf/nginx.conf。

     (2)鉴于原有的naxsi_core.rules文件中规则不足,最好是采用本文档中的配置规则。

第四步:编译安装Nginx

查看系统原来编译Nginx的参数:

[qiang @srv-dfh526 ~]#nginx  -V

nginx version: nginx/1.3.0

TLS SNI support enabled

configure arguments:--with-http_stub_status_module --with-http_gzip_static_module--with-http_ssl_module --prefix=/usr/local/nginx--with-openssl=/root/install/openssl-1.0.1c --with-pcre=/root/install/pcre-8.20

在原来的编译参数的首行加入--add-module=/root/install/naxsi-core-0.51-1/naxsi_src。

[[email protected]]#./configure  

--add-module=/root/install/naxsi-core-0.51-1/naxsi_src\

--with-http_stub_status_module\

--with-http_gzip_static_module\

--with-http_ssl_module \

--prefix=/usr/local/nginx\

--with-openssl=/root/install/openssl-1.0.1c\

--with-pcre=/root/install/pcre-8.20

[[email protected]]# make &amp;&amp; make install

注:上述的参数可以根据实际情况选择,但是标红的需要有。

第五步:验证nginx是否安装成功

[[email protected]]# nginx

nginx: [warn] low addressbits of 192.168.1.65/26 are meaningless in /etc/nginx/nginx.conf:78

[[email protected]]# ps -ef |grep nginx

root      3086    1  0 10:53 ?        00:00:00 nginx: master process nginx

root      3087 3086  1 10:53 ?        00:00:00 nginx: worker process

root      3088 3086  1 10:53 ?        00:00:00 nginx: worker process

root      3089 3086  1 10:53 ?        00:00:00 nginx: worker process

root      3090 3086  1 10:53 ?        00:00:00 nginx: worker process

root      3093 3073  4 10:53 pts/1    00:00:00 grep nginx

第六步:配置过滤条件

切换目录到与nginx.conf同目录下,新建nbs.rules文件。

[qiang@localhost nginx]#vim nbs.rules

##LearningMode;

#Enables learningmode--stop

SecRulesEnabled;

##Disables learning

##SecRulesDisabled;

DeniedUrl"/RequestDenied";

## check rules

CheckRule "$SQL &gt;=8" BLOCK;

CheckRule "$RFI &gt;=8" BLOCK;

CheckRule "$TRAVERSAL&gt;= 8" BLOCK;

CheckRule "$EVADE&gt;= 8" BLOCK;

CheckRule "$XSS &gt;=8" BLOCK;

############################################################

##      STOP  ALL   RULES(如果不需要可以关闭全部过滤规则)  ##

#BasicRule wl:0;

BasicRulewl:1,2,10,11,12,13,14;

BasicRule wl: 1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016;

BasicRulewl:1100,1101,1102,1103,1104,1105,1106,1107,1108,1109;

BasicRulewl:1200,1202,1203,1204,1205,1206;

BasicRulewl:1310,1311,1312,1313,1314,1315,1318;

BasicRulewl:1400,1401,1402;

BasicRule wl:1500,1501,1502,1503;

 注:该nbs.rules文件的规则需要根据不同的业务应用制定。

第七步:配置nginx.conf

http{

    #必须配置

    include       naxsi_core.rules;

    include       mime.types;

    default_type  application/octet-stream;

    .......

    server {

        listen       80;

        server_name  localhost centoshost.com;

        charset utf-8;

        .......

        location /wavsep/ {

            .......

            #每一个location配置首行都需要添加该行

            includenbs.rules;

        }

        #与应用处于相同的server配置

        location /RequestDenied {

            error_page  404 /404.html;

        }

注:wavsep表示一个demo应用。

第八步:重启nginx

nginx:[warn] low address bits of 192.168.1.65/26 are meaningless in/etc/nginx/nginx.conf:78

nginx:the configuration file /etc/nginx/nginx.conf syntax is ok

nginx:configuration file /etc/nginx/nginx.conf test is successful

[qiang@localhostnginx]# nginx -s reload

第九步:测试拦截规则是否启用

上述的规则仅过滤“&lt;”、“&gt;”。

测试XSS注入:

<a href="http://s3.51cto.com/wyfs02/M00/59/3A/wKioL1TMOeeSQQrFAAFW1kAODH4636.jpg" target="_blank"></a>

结果:

<a href="http://s3.51cto.com/wyfs02/M01/59/3A/wKioL1TMOfTT31s9AAE0gGY-_xc260.jpg" target="_blank"></a>

第十步:替换应用中的ajax

<code>function</code> <code>htmlEncode (str){</code>

<code>    </code><code>var</code> <code>s = </code><code>""</code><code>;</code>

<code>    </code><code>if</code> <code>(str.length == 0) </code><code>return</code> <code>""</code><code>;</code>

<code>    </code><code>//s = str.replace(/ /g, "&amp;nbsp;");</code>

<code>    </code><code>//s = str.replace(/&amp;/g, "&amp;amp;");</code>

<code>    </code><code>s = str.replace(/&lt;/g, </code><code>"&amp;lt;"</code><code>);</code>

<code>    </code><code>s=s.replace(/%3C/g,</code><code>"&amp;lt;"</code><code>);</code>

<code>    </code><code>s=s.replace(/%3c/g,</code><code>"&amp;lt;"</code><code>);</code>

<code>    </code><code>s = s.replace(/&gt;/g, </code><code>"&amp;gt;"</code><code>);</code>

<code>    </code><code>s = s.replace(/%3E/g, </code><code>"&amp;gt;"</code><code>);</code>

<code>    </code><code>s = s.replace(/%3e/g, </code><code>"&amp;gt;"</code><code>);</code>

<code>    </code><code>//s = s.replace(/\'/g, "&amp;#39;");</code>

<code>    </code><code>//s = s.replace(/\"/g, "&amp;quot;");</code>

<code>    </code><code>//s = s.replace(/\n/g, "&lt;br&gt;");</code>

<code>    </code><code>return</code> <code>s;</code>

<code>}</code>

<code>function</code> <code>ajaxJsonCall(url, data, callback) {</code>

<code>    </code><code>var</code> <code>source="</code><code>";</code>

<code>    </code><code>if(typeof(data) == "</code><code>object</code><code>"){</code>

<code>        </code><code>source=htmlEncode(JSON.stringify(data));</code>

<code>        </code><code>source=JSON.parse(source);</code>

<code>        </code><code>data=source;</code>

<code>    </code><code>}else if(typeof(data) == "</code><code>string</code><code>"){</code>

<code>        </code><code>source=htmlEncode(data);</code>

<code>    </code><code>}</code>

<code>    </code><code>$.ajax({</code>

<code>        </code><code>url: app_path + '/' + url,</code>

<code>        </code><code>//contentType: "</code><code>application/x-www-form-urlencoded;charset=utf-8</code><code>",</code>

<code>        </code><code>data: data,</code>

<code>        </code><code>type: "</code><code>POST</code><code>",</code>

<code>        </code><code>dataType: "</code><code>json",</code>

<code>        </code><code>error:</code><code>function</code><code>(msg){msg.rtnCode='999999</code><code>';msg.rtnMsg='</code><code>发生未知异常</code><code>';callback(msg)},</code>

<code>        </code><code>success: callback</code>

<code>    </code><code>});</code>

<code>    </code><code>/*data = replacechar(data);  </code>

<code>    </code><code>$.post(app_path + '</code><code>/</code><code>' + url, data, callback, '</code><code>json');*/</code>

版权声明:原创作品,如需转载,请注明出处。否则将追究法律责任

本文转自 梦朝思夕 51CTO博客,原文链接:http://blog.51cto.com/qiangmzsx/1610200

继续阅读