新浪SAE如何处理泛域名的问题
?
今天看到论坛社区总有人问这个问题,特意整理了一下。
针对qmei.sinaapp.com以及qlove.sinaapp.com这个例子,如何做到点击链接后,跳转到其他网站。
如图
?
?
?
?
?
?
?
?
?
?
?
这样子就可以实现这个功能了。
另附录上config.yaml文件常见配置
?
使用指南
?设置
????例子:
????name:?saetest
????version:?1?
????编辑saetest/1/config.yaml,增加handle段,如:
????name:?saetest
????version:?1
????handle:
????-?rewrite:?if(!is_dir()?&&?!is_file())?goto?"index.php?%{QUERY_STRING}"?
????编辑完成后,通过SVN代码部署工具提交即可生效。或者你也可以通过在线代码编辑器修改config.yaml
????如果通过SVN部署,只需要在默认版本所在目录下,如,您的应用名为devapp,默认版本是3,那么请在devapp/3/下创建config.yaml文件,按下以下语法编写,然后通过svn?commit部署完成即可生效。
?语法说明
????AppConfig的语法分两种,一种是简单的参数罗列方式,一种是灵活的表达式语法,不同的功能会用到不同的类型的语法。
??参数方式
???目录默认页面
????-?directoryindex:?file_list
????file_list?中各个文件名以空格分隔,directoryindex在?yaml?文件中仅有一项
????例子:
????-?directoryindex:?aaa.php?bbb.html
???自定义错误页面
????-?errordoc:?httpcode?error_file
????httpcode?是诸如404、302之类的http响应码,error_file是服务器以?httpcode响应请求时响应的文件。errordoc在yaml中可以配置多项。
????-?errordoc:?404?/path/404.html
????-?errordoc:?403?/path/403.html
??表达式语法
????其他功能需要用到表达式语法,其形式为:
????if?(expression)?do_something
????expression?有如下形式:
????1)?in_header["header_name"]?op?string_or_digit
????2)?out_header["header_name"]?op?string_or_digit
????3)?path?op?string
????4)?query_string?op?string
????5)?is_file()
????6)?is_dir()
????关于以上形式说明如下:
????1)?in_header?是请求头,out_header?是响应头,header_name?是?header?的名字,具体的请求头和响应头参考RFC官方文档
????2)?op?是操作符,有?~(正则匹配)?!~(正则不匹配)?==(相等,用于字符串和数字)?!=(不相等,用于字符串和数字)?>,?>=,?<,?<=(比较操作符仅用于整形数字)
????3)?string?是形如?"xxxx"?的字符串
????4)?string_or_digit?表示?string?或者?digit,根据?op?的种类,后面跟?string?或者?digit
????5)?path?是系统宏,表示用户请求的?url?去掉主机部分和查询串后剩下的部分
????6)?query_string?是系统宏,表示查询串,一般是url中问号后面的内容
????7)?is_file()?和?is_dir?是系统函数,判断?path?是文件还是目录,!is_file(),!is_dir()?分别是其否定形式。
????表达式语法用于以下功能:
???压缩
????-?compress:?if?(single_express)?compress
????在?compress?中?single_express?表示单一的表达式,不能用?&&?做复合,in_header,out_header,path?都可以出现在?single_express?中
????例如:
????-?compress:?if(out_header["Content-Length"]?>=?10240)?compress
????-?compress:?if(in_header["Referer"]?==?"gphone")?compress
????-?compress:?if(path?~?"/big/")?compress
???URL重写
????-?rewrite:?if?(complex_express)?goto?target_url
????在?rewrite?中,complex_express?可以用?&&?连接,组成复合表达式。除?out_header?(没办法根据响应?header?做重定向)?外都可以出现在?rewrite?的?if?中,并且?path?只能出现一个(如果有多个,只有最后一个生效,其它被忽略),当省略?path?时,表示任意请求。
????target_url?表示重定向的目标url,在target_url?可以以?$N?的形式表示?path?中匹配到的内容,%N?的形式表示最后一个query_string?中匹配到的内容,因为query_string?可以在?if?中出现多次,以%{QUERY_STRING}?表示查询串。?
?
????例如:
????-?rewrite:?if(query_string?~?"^(so)$"?&&?path?~?"zhaochou$")?goto?"/url/%1"
????-?rewrite:?if(is_dir(?)?&&?path?~?"urldir/(.*)")?goto?"/url/$1"
????-?rewrite:?if(?!is_file()?&&?!is_dir())?goto?"index.php?%{QUERY_STRING}"
???指定过期时间和头信息
????-?expire:?if?(single_express)?time?seconds
????-?mime:?if?(single_express)?type?content-type
????seconds?是秒数,content-type?是表示文档类型的字符串。
????例如:
????-?expire:?if(in_header["referer"]?~?"sina")?time?10
????-?mime:?if(path?~?"\.pdf2$")?type?"application/pdf"
???设置响应header?Content-Type
????如果?url?请求文件的扩展名是?pdf2,设置?Content-Type?为?application/pdf
????-?mime:?if(path?~?"\.pdf2$")?type?"application/pdf"
?
????只要请求?header?referer?包含字符串?sina,就设置?Content-Type?为?text/plain
????-?mime:?if(in_header["referer"]?~?"sina")?type?"text/plain"
?
????在?expire?和?mime?中?single_express?表示单一的表达式,不能用?&&?复合,in_header,path?都可以出现在?single_express?中,并且?op?只能是?~?或者?==,即只支持正则匹配和字符串比较。
?
???基于主机的访问控制
????禁止127.0.0.1?访问private目录
????-?hostaccess:?if(path?~?"/private/")?deny?"127.0.0.1"?
?
????只允许127.0.0.1?访问.conf结尾的文件
????-?hostaccess:?if(path?~?"\.conf$")?allow?"127.0.0.1"?
?
????禁止127.0.0.1?的所有访问(这个要慎用)
????-?hostaccess:?deny?"127.0.0.1"?
?
????对cron任务保护,防止被外部抓取,我们将cron任务放在cron目录下(sae中cron服务执行时,走的是内部网络)
????-?hostaccess:?if(path?~?"/cron/")?allow?"10.0.0.0/8"?允许10打头的所有IP?
?
?
????对于屏蔽一组IP地址,可以写成子网掩码形式,或者将多个IP之间加以空格。子网掩码形式如下:
????-?hostaccess:?if(path?~?"/cron/")?deny?"108.192.8.0/24"?屏蔽108.192.8打头的所有IP?
????多个IP形式如下:
????-?hostaccess:?allow?"108.134.13.24?108.122.122.13"?允许108.134.13.24和108.122.122.13这两个IP
????或:
????-?hostaccess:?allow?"108.134.13.24","108.122.122.13"
?
?
????(ip地址需要加引号,all代表所有IP地址,具体可以参考Apache配置.allow是白名单方式,deny是黑名单)?
?
???简单的认证
????访问secret目录需要密码,允许用户test用密码123qwe访问,用户coder用密码123asd访问
????-?passwdaccess:?if(path?~?"/secret/")?passwd?"test:123qwe?coder:123asd"?
?
????访问.text结尾的文件需要密码,允许用户writer用密码123zxc
????-?passwdaccess:?if(path?~?"\.text$")?passwd?"writer:123zxc"?
?
????所有访问都要密码,允许用户writer用密码123zxc访问
????-?passwdaccess:?passwd?"write:123zxc"?
?
????用户的网站后台程序都放在admin目录下,需要对admin目录做密码保护
????-?passwdaccess:?if(path?~?"/admin/")?passwd?"admin:admin123"
?
?
????在?hostaccess?和?passwdaccess?中?single_express?表示单一的表达式,不能用?&&?复合,in_header,path?都可以出现在single_express?中,并且?op?只能是?~?或者?==,即只支持正则匹配和字符串比较,并且?if?语句可以省略,表示无条件执行访问控制
?
备注和说明
????更多例子:
?目录默认页面
????当访问url没有指定文件时,返回aaa.php,如果其不存在,则返回bbb.html
????-?directoryindex:?aaa.php?bbb.html?
?自定义错误页面
????遇到?404?错误,返回?/path/404.html?文件。遇到?403?错误,返回?/path/404.html?文件
????-?errordoc:?404?/path/404.html
????-?errordoc:?403?/path/403.html?
?压缩
????当页面内容大于?10K字节时压缩
????-?compress:?if(out_header["Content-Length"]?>=?10240)?compress?
?
????当请求?header?Content-Type?中包含?text?时压缩
????-?compress:?if(out_header["Content-Type"]?~?"text")?compress?
?
????当响应?header?Referer?等于?gphone?时压缩
????-?compress:?if(in_header["Referer"]?==?"gphone")?compress?
?
????当请求的?url?包含“/big/”?时压缩
????-?compress:?if(path?~?"/big/")?compress?
?
????注:对所有的压缩,请求?header?Accept-Encoding?包含?gzip,deflate?是题中之意。
????压缩配置注意事项
????通常情况,我们根据响应头Content-length,判断是否需要压缩,例如:if(out_header["Content-Length"]>=10240)?compress,这个静态页面,如js,css,html都是没有问题的。
????但是对php脚本,响应header中,没有Content-length这个头,它使用Transfer-Encoding:?chunked,这个头表示页面输出用chunked编码。此时要实现压缩,可以通过配置appconfig,同时在php脚本中输出相应头的方式实现。
????例如在appconfig中写?if(out_header["Use-Compress"]?==?"1")?compress,在需要压缩的php脚本中写
????压缩生效检查
????检查是不是输出了响应头:Content-Encoding:?gzip。
????IE下的HttpWatch和FireFox下的Firebug都可以查看页面的响应header。
?页面重定向
????当?url?匹配?urldir/(.*)?,并且?输入?header?referer?等于?sina?时,跳转至页面?/usr/$1,$1?表示刚刚匹配的?urldir/(.*)?中的?(.*)?部分。
????-?rewrite:?if?(path?~?"urldir/(.*)"?&&?in_header["referer"]?==?"sina")?goto?"/url/$1"?
?
????当?url?匹配?urldir/(.*),并且请求的是一个目录时,跳转至?/url/$1
????-?rewrite:?if(is_dir(?)?&&?path?~?"urldir/(.*)")?goto?"/url/$1"?
?
????当?url?匹配?path,并且请求的不是一个文件时,跳转至?/url/query.php
????-?rewrite:?if(!?is_file()?&&?path?~?"path")?goto?"/url/query.php"?
?
????当查询串等于so,并且?url?以?zhaochou?结尾时,跳转至?/url/%1,%1?表示?query_string?匹配到的部分。
????-?rewrite:?if(query_string?~?"^(so)$"?&&?path?~?"zhaochou$")?goto?"/url/%1"?
?
????当查询串不包含sohu,并且?url?以?zhaochou?结尾时,跳转至?/url/query.php?%{QUERY_STRING},%{QUERY_STRING}?表示查询串。
????-?rewrite:?if(query_string?!~?"sohu"?&&?path?~?"zhaochou$")?goto?"/url/query.php?${QUERY_STRING}"?
?
????如果?url?既不是文件,也不是目录,跳转至?index.php?%{QUERY_STRING}
????-?rewrite:?if(?!is_file()?&&?!is_dir())?goto?"index.php?%{QUERY_STRING}"?
?
?设置响应头的mime类型
????如果?url?请求文件的扩展名是?pdf2,设置?Content-Type?为?application/pdf
????-?mime:?if(path?~?"\.pdf2$")?type?"application/pdf"?
?
????只要请求?header?referer?包含字符串?sina,就设置?Content-Type?为?text/plain
????-?mime:?if(in_header["referer"]?~?"sina")?type?"text/plain"?
?
?页面过期
????如果请求?header?Referer?包含?字符串sina,设置过期时间10s
????-?expire:?if(in_header["referer"]?~?"sina")?time?10?
?
????如果?url?以?lib\.js?结尾,设置过期时间100s
????-?expire:?if(path?~?"lib\.js$")?time?100?
?
【FAQ】:?
????1.?如果有形如?path?~?"^(.*)$"?类的请求,一定要加上?is_file?或?is_dir?之类的判断,防止无穷的rewrite。?
????2.?path?是用户请求的资源路径,比如请求?http://qlove.sinaapp.com/b/index.php?a=4,那么path就是?/b/index.php。?
????3.?在goto语句中,虽然某些时候可以不以/开头,但是强烈建议以/开头。?
????生效检查
????检查是不是输出了响应头:Cache-Control。IE下的HttpWatch和FireFox下的Firebug都可以查看页面的响应header。
1 楼 gosin 21 小时前 http://qmei.sinaapp.com