[asp]让你知道codepage的重要

作者:萧萧小雨

这几天研究UTF-8编码,太晕了,把我的看法和各位讨论讨论。
欢迎来批啊。以下都是我的想法,哪里有不对的请不吝赐教,帮忙指出来。

相关的题外话:

一、操作系统
window系统内部都是unicode的。文件夹名,文件名等都是unicode的,任何语言系统下都能正常显示。

二、输入法:
微软拼音输出的是Unicode的,智能ABC输出是简体中文的(所以智能ABC在非简体中文系统根本不能用,只能打英文)。

三、网页的textarea
网页的textarea是用unicode显示的。所以往里打什么字都能显示。而一些flash做的输入框就不行了。

四、Access2000
access里面保存的数据是unicode的,在任何语言系统下都能显示。
如果数据视图查看有些字符不正常,那是因为显示所用的字体不是Unicode字体,
换用Arial Unicode MS 字体就能全部显示了。(access帮助,搜索,输入unicode,有说明)

五、Word
word里的繁简转换,简体转换到繁体后,内码仍是简体中文的,其实只是简体中的繁体字。

六、ASP内部是Unicode的,所有文本都是Unicode存储的。需要时转换到指定字符集。

首先说下结论:
<%@ codepage=936%>简体中文
<%@ codepage=950%>繁体中文
<%@ codepage=65001%>UTF-8

codepage指定了IIS按什么编码读取传递过来的串串(表单提交,地址栏传递等)。

也指定了所有文本变量从Unicode转换到的编码,
也就指定了从数据库取出的数据从Unicode转换到的编码。(注意这个,很重要。)

关键字:
读取:一个串串,按简体读取是一些字,按繁体读取是一些字,串串本身编码没有变。

转换:系统主动的转换,比如从Unicode的“化”字到Big5的“化”字,内码变成Big5的。如果Big5没有对应的字,保留Unicode形式(&#xxxx;)

简体中文:化六个结论
Unicode16进制形式:化六个结论
Unicode10进制形式:化六个结论

下面是我推测出来的编码转换的过程:
客户端:输入法Unicode–输入框unicode–从Unicode按charset转换到对应编码()–表单发送编码

服务器端:IIS解开表单编码–按codepage指定编码读取–转换到对应的Unicode–可以用request("")读取了–进行一些处理–以Unicode编码保存到数据库

服务器端:读取数据库的Unicode数据,转换到codepage指定编码—生成源代码–IE按charset读取显示。

下面举例说明:
例一:
假设有三个asp页面,典型的留言页面:
1.write.asp 简单的输入表单,提交到add.asp。
<META http-equiv="Content-Type" content="text/html; charset=big5">
2.add.asp 接收留言,保存到数据库
<%@ codepage=936%>
3.read.asp 从数据库取得留言,显示。
<%@ codepage=936%> charset=GB2312 或
<%@ codepage=950%> charset=big5

大家可以猜一猜,我在write.asp里用微软拼音输入法输入“化六个讨论”。最后在read.asp里会显示什么样?
是不是晕了。让我们从头分析。

例二:
把例一的add.asp的<%@ codepage=936%>改为<%@ codepage=950%>,又会怎么样呢?

到这里发现了什么?
1.如果输入的文字和Charset对应的不同,一转换,就可能出现Unicode形式的字了。这里就是原因所在。以后整个过程都保留着。
2.Add.asp里codepage决定了保存到数据库的文字,用的是哪个语言对应的Unicode.如codepage=936,
那么数据库保存的就是简体中文的Unicode(数据库拿回简体中文系统,一切正常的),
codepage=950保存的就是繁体中文的Unicode.(拿回简体中文系统,就不对了)。

3.注意一下串串的变化过程:

1)输入法—CharsetUnicode—-指定字符集的映射
2)Charset—-表单编码串串简单编码
3)表单解码上步的逆过程,两步抵消了。
4)串串à按codepage读取串串没变,这步有可能“误会读取”
5)转为对应的Unicode Codepage指定字符集—-Unicode映射
6)中间处理,进数据库无变化,直接以Unicode形式进入
7)按codepage读取数据库 Unicode—-codepage指定字符集的映射
8)显示,按Charset指定字符集读取串串没变。

以例一说明:

例二:

晕了。现在来用用知识。

案例1。
简体中文系统下跑的好好的代码,放到国外空间上,数据库里乱码,原有的数据也乱码。
分析:因为大多数人平时用的都是简体中文系统,默认的codepage=936,所以平时大家不写也没有关系。
但到了国外空间问题就出来了。从数据库里的Unicode转换到英文编码去了,所以数据库原有的简体中文转换到英文后,按GB显示自然乱码。
如图,新输入的文字显示正常,但数据库里保存的是英文的Unicode的。
解决方法:全部加上<%@codepage=936即可%>。
全程只有简体中文与对应Unicode间的转换。

案例二:
简体中文的代码和数据,想转为完全的繁体版,该怎么办?
分析:1。代码文件编码全部改为Big5的,文件本身保存编码选繁体。
2.<%@ codepage=936 %>
3.Charset=big5
4.access版本无所谓,因为access里的数据是Unicode的。
5.好了,代码可以在纯繁体系统下跑了。
6.遗留问题:原有的简体中文数据读出会有一些问号。效果同例一的950读取,big5显示。因为从简体中文的Unicode转换到繁体中文了,有些字繁体中没有,就会出问号。
7.解决:用一个临时asp页,codepage=65001,读出为简体中文的Unicode,用一个Unicode->Big5的函数,转为繁体中文,然后写回数据库,应该行了吧?

两个案例完全是我按照理论推导出来了,未经证实。
有类似经历的欢迎批评指正。

ISAPI_Rewrite Examples

Examples
Emulating host-header-based virtual sites on a single site
For example you have registered two domains www.site1.com and www.site2.com. Now you can create two different sites using single physical site. Add the following rules to your httpd.ini file:

[ISAPI_Rewrite]

#Fix missing slash char on folders
RewriteCond Host: (.*)
RewriteRule ([^.?]+[^.?/]) http://$1$2/ [I,R]

#Emulate site1
RewriteCond Host: (?:www.)?site1.com
RewriteRule (.*) /site1$1 [I,L]

#Emulate site2
RewriteCond Host: (?:www.)?site2.com
RewriteRule (.*) /site2$1 [I,L]

Now just place your sites in /site1 and /site2 directories.

or you can use more generic rules:

[ISAPI_Rewrite]

#Fix missing slash char on folders
RewriteCond Host: (.*)
RewriteRule ([^.?]+[^.?/]) http://$1$2/ [I,R]

RewriteCond Host: (www.)?(.+)
RewriteRule (.*) /$2$3

The directory names for sites should be like /somesite1.com, /somesite2.info, etc.

Using different namespaces on development and live servers
Suppose you are developing rules for a website that will be deployed to a /livesite/ folder on a live server. However, on a development machine you need to store files in the /develop/ folder. In this case you could use UriMatchPrefix and UriFormatPrefix directives to minimize a number of changes those will be needed for a namespace change:

[ISAPI_Rewrite]

#specify namespaces with UriMatchPrefix and UriFormatPrefix
UriMatchPrefix /develop
UriFormatPrefix /develop

#rules are going here

#really we are checking for /develop/sampleN.htm and formatting to /develop/sampleN.asp
RewriteRule /sample1.htm /sample1.asp [I,L]
RewriteRule /sample2.htm /sample2.asp [I,L]
RewriteRule /sample3.htm /sample3.asp [I,L]

#reset namespaces to default
UriMatchPrefix
UriFormatPrefix

The only things you will need to change before a deployment to a live server are values of UriMatchPrefix and UriFormatPrefix.

Using loops (Next flag) to convert request parameters
Suppose you wish to access physical URLs like http://www.myhost.com/foo.asp?a=A&b=B&c=C using requests like http://www.myhost.com/foo.asp/a/A/b/B/c/C and the number of parameters may vary from one request to another.

There exist at least two possible solutions. You could simply add a separate rule for each possible number of parameters or you could use a technique demonstrated by the following example.

[ISAPI_Rewrite]
RewriteRule (.*?.asp)(?[^/]*)?/([^/]*)/([^/]*)(.*) $1(?2$2&:?)$3=$4$5 [NS,I]

Note that this rule may break page-relative links to CSSs, images, etc. This is due to a change in the base path (parent folder of the page) that is being used by a browser to calculate complete resource URI. There are three possible solutions:

Use the rule given below. It does not affect base path.
Directly specify correct base path for a page with the help of tag.
Change all page-relative links to either root-relative or absolute form.

This rule will extract one parameter from request URL, append it to the end of the request string and restart rules processing from the beginning. So it will loop until all parameters will be moved to the right place (or until the RepeatLimit will be exceeded).

There also exist many variations of this rule with different separator characters. For example, to use URLs like http://www.myhost.com/foo.asp~a~A~b~B~c~C the following rule could be implemented:

[ISAPI_Rewrite]
RewriteRule (.*?.asp)(?[^~]*)?~([^~]*)~([^~]*)(.*) $1(?2$2&:?)$3=$4$5 [NS,I]

Running servers behind IIS
Assume we have internet server running IIS and several corporate servers running other platform. These servers are not directly accessible from the internet but only from our corporate network. Here is a simple example how to map another server into the IIS site’s namespace using proxy flag:

[ISAPI_Rewrite]
RewriteProxy /mappoint(.+) http://sitedomain$1 [I,U]

Moving sites from UNIX to IIS
This rules can help change the URL from /~username to /username and /file.html to /file.htm. It can be useful if you just moved your site from UNIX to IIS and keep getting hits to the old pages from search engines and other external pages.

[ISAPI_Rewrite]

#redirecting to update old links
RewriteRule (.*).html $1.htm
RewriteRule /~(.*) http://myserver/$1 [R]

Moving site location
Many webmasters asked for a solution to the following problem: They want to redirect all requests to one web server to another web server. Such problems usually arise when you need to establish a newer web server which will replace the old one over time. The solution is to use ISAPI_Rewrite on the old web server:

[ISAPI_Rewrite]

#redirecting to update old links
RewriteRule (.+) http://newwebserver$1 [R]

Browser-dependent content
It is sometimes necessary to provide browser-dependent content at least for important top-level pages, i.e. one has to provide a full-featured version for the Internet Explorer, a minimum-featured version for the Lynx browsers and an average-featured version for all others.

We have to act on the HTTP header “User-Agent”. The sample code does the following: If the HTTP header “User-Agent” contains “MSIE”, the target foo.htm is rewritten to foo.IE.htm. If the browser is “Lynx” or “Mozilla” of version 1 or 2 the URL becomes foo.20.htm. Other browsers receive page foo.32.html. All this is done by the following ruleset:

[ISAPI_Rewrite]

RewriteCond User-Agent: .*MSIE.*
RewriteRule /foo.htm /foo.IE.htm [L]

RewriteCond User-Agent: (?:Lynx|Mozilla/[12]).*
RewriteRule /foo.htm /foo.20.htm [L]

RewriteRule /foo.htm /foo.32.htm [L]

Dynamically generated robots.txt
robots.txt is a file that search engines use to discover URLs that should or should not be indexed. But creation of this file for large sites with lot of dynamic content is a very complex task. Have you ever dreamed about dynamically generated robots.txt? Let's write robots.asp script:

<%@ Language=Jscript EnableSessionState=False%>
<%

//The script must return plain text
Response.ContentType=”text/plain”;

/*
Place generation code here
*/

%>

Now make it robots.txt using single rule:

[ISAPI_Rewrite]

RewriteRule /robots.txt /robots.asp

Making search engines to index dynamic pages
Content of the site stored in XML files. There is /XMLProcess.asp file that processes XML files on server and returns HTML to end user. URLs to the documents have a form of:
http://www.mysite.com/XMLProcess.asp?xml=/somdir/somedoc.xml
But many popular search engines will not index such documents because URLs contain question mark (document is dynamically generated). ISAPI_Rewrite can competely eliminate this problem.

[ISAPI_Rewrite]

RewriteRule /doc(.*).htm /XMLProcess.asp?xml=$1.xml

Now to access documents use URL like http://www.mysite.com/doc/somedir/somedoc.htm. Search engines will never know that physically there is no somedoc.htm file and content is dynamically generated.

Negative e­xpressions (NOT)
Sometimes you need to apply rule when some pattern not matches. In this case you may use so called Forward Lookahead Asserts in regular e­xpressions.

For example you need to move all users not using Internet Explorer to the other location:

[ISAPI_Rewrite]
# Redirect all non Internet Explorer users
# to another location
RewriteCond User-Agent: (?!.*MSIE).*
RewriteRule (.*) /nonie$1

Dynamic authentication
For example we have some members area on the site and we need password-protect files in this area but we don't like to use built-in server security. In this case it is possible to create ASP script (call it proxy.asp) that will proxy all requests to the members area and check for required permissions. Here is a simple template for this page where you can put your own authorization code:

<%@ Language=Jscript EnableSessionState=False%>
<%
function Authorize()
{

//Check if the user is authorized to view a resource here
//Return true if user has a required permission, otherwise return false

return true;
}
if(!Authorize())
{
//Redirect to the login page
Response.Redirect(“http://mysite.com/LoginPage.asp?ref=”+Request.QueryString.Item);
Response.End()
}
var WinHttpReq = new ActiveXObject(“WinHttp.WinHttpRequest.5”);
WinHttpReq.Open(Request.ServerVariables(“REQUEST_METHOD”).Item, Request.QueryString.Item, true);
var headers=String(Request.ServerVariables(“ALL_RAW”)).split(”
“);
for(i=0; i<headers.length && headers[i]; i++)
{
header = headers[i].match(/([w-.]+):s*([ S]*)/);
if(header)
WinHttpReq.SetRequestHeader(header[1],header[2]);
}
if(lngCount = Request.TotalBytes)
{
var data=Request.BinaryRead(lngCount);
WinHttpReq.Send(data);
} else {
WinHttpReq.Send();
}
if(!WinHttpReq.WaitForResponse(15))
{
WinHttpReq.Abort();
Response.Status=”408 Request Timeout”;
} else {
Response.Status = “” + WinHttpReq.Status + ” ” + WinHttpReq.StatusText;
headers=String(WinHttpReq.GetAllResponseHeaders()).split(”
“);
for(i=0; i<headers.length && headers[i]; i++)
{
header = headers[i].match(/([w-.]+):s*([ S]*)/);
if(header)
Response.AddHeader(header[1],header[2]);
}
Response.Write(WinHttpReq.ResponseText);
}
%>

Now we need to configure ISAPI_Rewrite to proxy requests through this page:

[ISAPI_Rewrite]
# Proxy all requests through proxy.asp
RewriteRule /members(.+) /proxy.asp?http://mysite.com/members$1

Blocking inline-images (stop hot linking)
Assume we have some pages with inlined GIF graphics under http://www.mysite.com/. These graphics are nice, so others directly incorporate them via hyperlinks to their pages. We don't like this practice because it adds useless traffic to our server.

While we cannot 100% protect the images from inclusion, we can at least restrict the cases where the browser sends a HTTP Referer header.

[ISAPI_Rewrite]
RewriteCond Host: (.+)RewriteCond Referer: (?!http://1.*).*RewriteRule .*.(?:gif|jpg|png) /block.gif [I,O]

Regular Expressions Testing Tool
RXTest utility could be used to simulate rule …

ISAPI_rewrite中文手册

配置:
在NT 2000 XP和2003平台上,在系统帐户下应该INETINFO程序应该与IIS5以共存模式过滤器运行。所以系统帐户应该给予对所有的ISAPI-REWIRITE DLLS 和所有的HTTPD。INI文件至少可读权限,我们也推荐对给予系统帐户对于所有包括HTTPD。INI文件的文件夹的可写权限,这将允许产生HTTP。PARSE。ERRORS文件,这些文件包含配置文件语法错误。对于PROXY模块也需要额外的权限,因为它将运行于连接池或HIGH-ISPLATED应用模式,IIS帐户共享池和HIGH-ISOLATION池应被给予 对RWHELPERE。DLL的可读权限。缺省情况下IWAM-《计算机名》被用于所有的池,在相应的COM+应用设置中应借助COM+ADMINISTRATION MMC SNAP-IN建立池帐户
配置文件格式化:

有两种形式的配置文件-GLOBAL(SERVER-LEVEL)和INDIVIDUAL(SITE-LEVAL)文件,GLOBAL配置文件应被命名为HTTPD.INI并出现在ISAPI-REWRITE安装目录中,文件的快捷方式通过开始菜单提供,INDIVIDUAL配置文件应名为HTTPD。INI并且能够出现在虚拟站点的物理根目录中,两种类型的格式化是相同的并是标准的WINDOWS。INI文件,所有的指令都应该放在这一部分并且所有指令都应该以分隔线放置,任何这一部分以外的文本都将被忽略

HTTPD.INI文件示例

[ISAPI_Rewrite]

# This is a comment

# 300 = 5 minutes
CacheClockRate 300
RepeatLimit 20

# Block external access to the httpd.ini and httpd.parse.errors files
RewriteRule /httpd(?:.ini|.parse.errors) / [F,I,O]

# Block external access to the Helper ISAPI Extension
RewriteRule .*.isrwhlp / [F,I,O]

# Some custom rules
RewriteCond Host: (.+)

RewriteCond 指令

Syntax:(句法) RewriteCond TestVerb CondPattern [Flags]
这一指令定义一个条件规则,在 RewriteRule 或者 RewriteHeader或 RewriteProxy指令前预行RewriteCond指令,后面的规则 只有它的,模式匹配URI的当前状态并且额外的条件也被应用才会被应用。

TestVerb

Specifies verb that will be matched against regular expression.
特别定义的动词匹配规定的表达式
TestVerb=(URL | METHOD | VERSION | HTTPHeaderName: | %ServerVariable) where:

URL – returns Request-URI of client request as described in RFC 2068 (HTTP 1.1);
返回客户端在RFC2068中描述的需求的Request-URI
METHOD – returns HTTP method of client request (OPTIONS, GET, HEAD, POST, PUT, Delete or TRACE);
返回客户端需求(OPTIONS, GET, HEAD, POST, PUT, Delete or TRACE)的HTTP方法
VERSION – returns HTTP version;
返回HTTP版本
HTTPHeaderName – returns value of the specified HTTP header. HTTPHeaderName can be any valid HTTP header name. Header names should include the trailing colon “:”. If specified header does not exists in a client's request TestVerb is treated as empty string.
返回特定义的HTTP头文件的值
HTTPHeaderName =
Accept:
Accept-Charset:
Accept-Encoding:
Accept-Language:
Authorization:
Cookie:
From:
Host:
If-Modified-Since:
If-Match:
If-None-Match:
If-Range:
If-Unmodified-Since:
Max-Forwards:
Proxy-Authorization:
Range:
Referer:
User-Agent:
Any-Custom-Header
得到更多的关于HTTP头文件的和他们的值的信息参考RFC2068

ServerVariable 返回特定义的服务器变量的值 。例如服务器端口,全部服务器变量列表应在IIS文档中建立,变量名应用%符预定;
CondPattern
The regular expression to match TestVerb
规则表达式匹配TestVerb
[Flags]
Flags is a comma-separated list of the following flags:

O (nOrmalize)
Normalizes string before processing. Normalization includes removing of an URL-encoding, illegal characters, etc. This flag is useful with URLs and URL-encoded headers
RewriteRule 指令
Syntax: RewriteRule Pattern FormatString [Flags]
这个指令可以不止发生一次,每个指令定义一个单独的重写规则,这些规则的定义命令很重要,因为这个命令在应用运行时规则是有用途的

I (ignore case)
不管大小写强行指定字符匹配,这个FLAG影响RewriteRule指令和相应的RewriteCond 指令
F (Forbidden)
对客户端做反应,停止REWRITING进程并且发送403错误,注意在这种情况下FORMATSTRING 是无用的并可以设置为任何非空字符串。
L (last rule)
不应用任何重写规则在此停止重写进程,使用这个FLAG以阻止当前被重写的URI被后面的规则再次重写
N (Next iteration)
强制REWRITINGENGINE调整规则目标并且从头重启规则检查(所有修改将保存),重启次数由RepeatLimit指定的值限制,如果这个数值超过N FLAG将被忽略
NS (Next iteration of the same rule)
以N标记工作不从相同的规则重启规则规则进程(例如强制重复规则应用),通过RepeatLimit指令指定一个反复实行某一规则的最大数目,
P (force proxy)
强制目的URI在内部强制为代理需求并且立即通过ISAPI扩展应付代理需求,必须确认代理字符串是一个有效的URI包括协议 主机等等否则代理将返回错误
R (explicit redirect)
强制服务器对客户端发出重定向指示即时应答,提供目的URI的新地址,重定向规则经常是最后规则
RP (permanent redirect)
几乎和[R]标记相同但是发布301HTTP状态而不是302HTTP状态代码
U (Unmangle Log)
当URI是源需求而不是重写需求时记载URI
O (nOrmalize)
在实行之前标准化字符串。标准化包括URL-ENCODING,不合法的字符的再移动等,这个标记对于URLS和URLS-ENDODED头是有用的
CL (Case Lower)
小写
CU (Case Upper)
大写
RewriteHeader directive
Syntax: RewriteHeader HeaderName Pattern FormatString [Flags]
这个指令是RewriteRule的更概括化变种,它不仅重写URL的客户端需求部分,而且重写HTTP头,这个指令不仅用于重写。生成,删除任何HTTP头,甚至改变客户端请求的方法
HeaderName
指定将被重写的客户头,可取的值与 RewriteCond 指令中TestVerb参数相同

Pattern
限定规则表达式以匹配Request-URI,
FormatString
限定将生成新的URI的FormatString
[Flags]
是一个下列FLAGS的命令分隔列表
I (ignore case)
不管大小写强行指定字符匹配,这个FLAG影响RewriteRule指令和相应的RewriteCond 指令
F (Forbidden)
对客户端做反应,停止REWRITING进程并且发送403错误,注意在这种情况下FORMATSTRING 是无用的并可以设置为任何非空字符串。
L (last rule)
不应用任何重写规则在此停止重写进程,使用这个FLAG以阻止当前被重写的URI被后面的规则再次重写
N (Next iteration)
强制REWRITINGENGINE调整规则目标并且从头重启规则检查(所有修改将保存),重启次数由RepeatLimit指定的值限制,如果这个数值超过N FLAG将被忽略

NS (Next iteration of the same rule)
以N标记工作不从相同的规则重启规则规则进程(例如强制重复规则应用),通过RepeatLimit指令指定一个反复实行某一规则的最大数目,

R (explicit redirect)
强制服务器对客户端发出重定向指示即时应答,提供目的URI的新地址,重定向规则经常是最后规则
RP (permanent redirect)
几乎和[R]标记相同但是发布301HTTP状态而不是302HTTP状态代码
U (Unmangle Log)
当URI是源需求而不是重写需求时记载URI
O (nOrmalize)
在实行之前标准化字符串。标准化包括URL-ENCODING,不合法的字符的再移动等,这个标记对于URLS和URLS-ENDODED头是有用的
CL (Case Lower)
小写
CU (Case Upper)
大写

要重移动头,FORMAT STRING模式应该生成一个空字符串,例如这一规则将从客户请求中重移代理信息
RewriteHeader User-Agent: .* $0
并且这一规则将把OLD-URL HEADER 加入请求中。
RewriteCond URL (.*)RewriteHeader Old-URL: ^$ $1
最后一个例子将通过改变请求方法定向所有的WEBDAV请求到/WEBDAV。ASP
RewriteCond METHOD OPTIONS
RewriteRule (.*) /webdav.asp?$1
RewriteHeader METHOD OPTIONS GET
RewriteProxy directive
Syntax: RewriteProxy Pattern FormatString [Flags]
强制目的URI在内部强制为代理需求并且立即通过ISAPI扩展应付代理需求,这将允许IIS作为代理服务器并且重路由到其他站点和服务器
Pattern
限定规则表达式以匹配Request-URI,
FormatString
限定将生成新的URI的FormatString
[Flags]
是一个下列FLAGS的命令分隔列表
D (Delegate security)
代理模式将试图以当前假冒的用户资格登陆远程服务器,
C (use Credentials)
代理模式将试图一在URL或基本授权头文件中指定的资格登陆远程服务器,用这个标记你可以使用http://user:password@host.com/path/ syntax 作为URL
F (Follow redirects)
缺省情况下ISAPI_Rewrite 将试图将MAP远程服务器返回的重定向指令到本地服务器命名空间,如果远程服务器返回重定向点到那台服务器其他的某个位置,ISAPI_Rewrite 将修改这一重定向指令指向本服务器名,这将避免用户看到真实(内部)服务器名称
使用F标记强制代理模式内部跟踪远程服务器返回的重定向指令,使用这个标记如果你根本不需要接受远程服务器的重定向指令,在WINHTTP设置中有重定向限制以避免远程重定向循环
I (ignore case)
不管大小写强行指定字符匹配
U (Unmangle Log)
当URI是源需求而不是重写需求时记载URI
O (nOrmalize)
在实行之前标准化字符串。标准化包括URL-ENCODING,不合法的字符的再移动等,这个标记对于URLS和URLS-ENDODED头是有用的
CacheClockRate directive
Syntax: CacheClockRate Interval
这个指令只在GLOBAL配置内容中出现,如果这个指令在SITE-LEVEL内容中出现将被忽略并把错误信息写入httpd.parse.errors 文件
ISAPI_Rewrite caches每次在第一次加载时配置,使用这个指令你可以限定当一个特定站点从缓存中清理的不活动周期,把这个参数设置的足够大你可以强制ISAPI_Rewrite 永不清理缓存,记住任何配置文件的改变将在下次请求后立即更新而忽略这个周期
Interval
限定特定配置被清理出缓存的不作为时间(以秒计),缺省值3600(1小时)
EnableConfig and DisableConfig directives
Syntax:
EnableConfig [SiteID|”Site name”]
DisableConfig [SiteID|”Site name”]
对所选站点激活或不激活SITE-LEVEL配置或者改变缺省配置,缺省SITE-LEVEL配置不激活,这个指令只出现在GLOBAL配置内容中
SiteID
Numeric metabase identifier of a site

Site name
Name of the site as it appears in the IIS console
不用参数使用这个命令将改变缺省配置到ENABLE/DISABLE配置进程
例子
下面例子将使配置仅作用于ID=1(典型是缺省站点)名字是MY SITE的站点
DisableConfig
EnableConfig 1
EnableConfig”My site”
下边例子将激活名称为SOMESITE配置因为它分割设置重载了缺省设置
EnableConfig”Some site”
DisableConfig
EnableRewrite and DisableRewrite directives
Syntax:
EnableRewrite [SiteID|”Site name”]
DisableRewrite [SiteID|”Site name”]
对所选站点激活或不激活重写或者改变缺省配置,缺省重写配置激活,这个指令只出现在GLOBAL配置内容中
SiteID
Numeric metabase identifier of a site

Site name
Name of the site as it appears in the IIS console.

不使用参数这个命令将全部激活或者不激活
RepeatLimit directive
Syntax: RepeatLimit Limit
这个指令可以出现在GLOBAL和SITE-LEVEL配置文件中,如果出现在GLOBAL配置文件中竟改变GLOBAL对于所有站点的限制,出现在SITE-LEVEL配置中竟只改变对于这个站点的限制并且这个限制不能超过GLOBAL限制
ISAPI_Rewrite在实行规则时允许循环,这个指令允许限制最大可能循环的数量,可以设置为0或1而不支持循环,
LIMIT
限制最大循环数量,缺省32
RFStyle directive
Syntax: RFStyle Old | New
Configuration Utility
ISAPI_Rewrite Full包括配置功用(可以在 ISAPI_Rewrite 程序组中启动),它允许你浏览测试状态并输入注册码(如果在安装过程中没有注册),并且调整部分与代理模式操作相关的产品功能,UTILITY是由三个页面组成的属性表
Trial page允许你浏览TIRAL状态并输入注册码(如果在安装过程中没有注册)
Settings page
这页包含对下列参数的编辑框

Helper URL
这个参数影响过滤器和代理模块之间的联系方式,它即可以是以点做前缀的文件扩展名(如 .isrwhlp)也可以是绝对路径,
第一种情况下扩展名将追加在初始请求URI上并且代理模块竟通过SCRIPT MAP激活,缺省扩展名isrwhlp在安装进程中加在global script map 中,如果你改变这个扩展名或者你的应用不继承global script map 设置你应该手动添加向script map 所需求的入口。这个应该有如下参数
Executable: An absolute path to the rwhelper.dll in the short form
Extension: Desired extension (.isrwhlp is default)
Verbs radio button: All Verbs
Script engine checkbox: Checked
Check that file exists checkbox: Unchecked
我们已经创建了一个WSH script proxycfg.vbs ,可以简单在一个a script maps中注册,她位于安装文件夹并且可以在命令行一如下方式运行
cscript proxycfg.vbs [-r] [MetabasePath]
Optional -r 强制注册扩展名
Optional MetabasePath parameter allows specification of the first metabase key to process. By default it is “/localhost/W3SVC”.
要在所有现存的 script maps 中注册你可以以如下命令行激活 script
cscript proxycfg.vbs -r
第二种情况下你应该提供一个URI作为'Helper URL'的值,你也应该map 一个 ISAPI_Rewrite的安装文件夹作为美意个站点的虚拟文件家
注意:根据顾客反应,IIS5(也许包括IIS4)对长目录名有问题。所以我们强烈推荐使用短目录名
Worker threads limit
这个参数限制在代理扩展线程池中工作线程数,缺省为0意味着这个限制等于处理器数量乘以2
Active threads limit
这个参数限制当前运行线程数,这个数量不可大于”Worker threads limit”. 缺省0意思是等于处理器数量
Queue size 这个参数定义最大请求数量,如果你曾经看到Queue timeout expired” 信息在 the Application event log中你可以增加这个参数
Queue timeout
这个参数定义你在内部请求队列中防止新请求的最大等待时间,如果你曾经看到Queue timeout expired” 信息在 the Application event log中你可以增加这个参数
Connect timeout
以毫秒设定代理模块连接超时
Send timeout
以毫秒设定代理模块发送超时
Receive timeout
以毫秒设定代理模块发送超时
About page.
It contains copyright information and a link to the ISAPI_Rewrite's web site.

Regular expression syntax
这一部分覆盖了 ISAPI_Rewrite规定的表达句法
Literals
所有字符都是原意除了 “.”, “*”, “?”, “+”, “(“, “)”, “{“, “}”, “[“, “]”, “^” and “$”.,这些字符在用“”处理时是原意,原意指一个字符匹配自身
Wildcard
The dot character “.” matches any single character except null character and newline character
以下为句法
Repeats
A repeat is an expression that is repeated an arbitrary number of times. An expression followed by “*” can be repeated any number of times including zero. An expression followed by “+” can be repeated any number of times, but at least once. An expression followed by “?” may be repeated zero or one times only. When it is necessary to specify the minimum and maximum number of repeats explicitly, the bounds operator “{}” may be used, thus “a{2}” is the letter “a” repeated exactly twice, “a{2,4}” represents the letter “a” repeated between 2 and 4 times, and “a{2,

策划人凭什么策划

  “凡事预则立,不预则废”。对于策划,古代早已有知,所谓策划就是一个谋划达成目标或事情的成功而先发的设想及其创造思维的过程,也是确保实现会管理活动决策和计划而进行有科学运作程序的谋划、构思和设计过程,是运用脑力的理性行为。策划已成为当今社会非常时髦的词语,与此产生的策划人也成了市场的高薪群体和关注度较高的人物,但对于策划人,凭什么策划?

  当前市场的策划人员,主要由以下几个方面的人群组成,一是出自媒体、记者行业的,由于长期在市场一线,拥有广泛的接触和见识,具有敏锐的洞察与思考;二是来自“海龟”,在国外接触了较新的理念和模式,认为可以指导企业实际;三是一批从国内知名企业或国外大公司出来的,认为掌握了先进的管理理念和市场运作,可以模仿创新运用;四是来自高校和研究机构的,将研究成果、理论与实际有限结合起来。由于背景、经历和学识各有不同,造成市场策划人士风格间的差异性,那么,是不是谁都可以成为策划人呢?策划人凭什么策划?

  一、从策划人的能力分析

  策划要根据现实的情况和信息进行谋划;具有明确的目的性;具有选择性和弹性;是按程序运作的系统工程,研究的根本是了解和掌握人的消费行为特征和消费心理特征,目的是通过了解和掌握人的消费行为特征和消费心理特征,预测和设计符合自己心愿的目标。从个人的能力上来说,我认为一个优秀的策划人士至少需要具备以下几个方面的能力:

  一是个人阅历与经历。策划人士需要足够的学历、丰富的工作经验、人生经历、广泛的社会关系和足以实践的社会空间。

  二是学习能力。策划人士需要勤奋的学习能力和科学的学习方式与方法,特别是借鉴别人的成功经验和失败的教训,需要实现知识储备和读万卷书的能力,需要与时俱进,不断学习新的知识和理念,因为策划人士是靠智力生存,需要比他人看得更深、更远、更广,这些都需要不断的思考和学习。

  三是思考能力。策划人的创意和创新,可以是模仿性的,可以是原创性的,需要具备联系思维、侧向移入和移出的思维、类比思维等,需要对于成功和失败的案例具有思考和总结的能力。

  四是团队协作精神。策划人需要具备合作精神,团队间的协作、部门间的协作和朋友、同事间的合作是策划人成功的必须条件。因为策划需要在不同的层面展开,需要不同部门之间的配合,需要整合资源和多学科之间的协调与探讨。

  五是创新能力。策划必须要有创新,具有创意。如做事的非常规思路、非常规的资源整合能力,善于在不同层面开展创新,如设计方面、事件营销方面、消费行为的洞察与了解方面、潜在需求的激发与引导方面等等,如对于递增需求,要寻求顾客对现有产品(或服务)的不满之处;对于派生需求,要寻求由主体消费引发的关联消费,同时对要素分析,分析全面开发产品潜在的功能要素。

  六是机会的把握和分析能力。首先善于分析不同的市场机会,具有敏锐的分析和对机会的把握能力,如对显在的市场机会要采用填补法,如差量填补、功能填补、结构填补;前兆型的市场机会要采用追随法,如梯度追随、时尚追随、关联追随;诱发型的市场机会要采用诱导法:如开发产品、营造概念、转变观念。突发型的市场机会要捕着。这要求策划人士对基本的分析工具如PEST环境扫描、SWOT分析、五力模型分析、产业分析、价值链分析、鱼骨架分析、雷达图等等,需要随时掌握市场信息情报资料;拥有适当的资源整合和个人鱼团队竞争实力;具有高度的进取心和敏感性。

  对于策划人,在策划过程中需要系统思考,全程运作,要设定目标、测定现状、为明确的活动设计计划。要区别策划和计划,计划是具体实施的细则,尤其是行动计划。任何策划都要最终落实到一个或多个计划来实施,不是所有的计划都隶属于某一策划;区别策划与决策,决策是做决定,重在优选方案,以抉择为重点;策划重在设想方案,以创造为主;区别策划和出点子,点子一般是解决某个具体问题,缺乏全局性、整体性和系统性,点子不具备可操作性,出点子只是策划的一部分。

  二、从策划人创意素质的培育分析

  策划需要创新和创意,既要低头拉车,又要抬头看路,在创意能力和思维的培育过程中,需要掌握相关的理论,如魔岛理论,认为创意的产生,有时象魔岛一样,在策划人的脑海中悄然浮现,不可捉摸,但它在人的潜意识中,也是经过无数的孕育过程,最后才得到结果;迁移理论认为迁移就是创意,当人们用不同的眼光去看原有的东西,眼光是新的,因而东西也是新的;拼图游戏,将不相干的东西象做拼图游戏那样组合起来,就是创意。在创意思考的过程中,利用刺激联想(风桶法),如日本有句俗话:“风吹时,卖木桶的会赚钱。”风吹,灰尘扬起—-盲人增多—-盲人要学三弦琴谋生—-三弦琴的需要量增加—-三弦琴要用猫皮做,猫皮的需要量随之增加—-猫的数目骤减,老鼠便增加—-木桶被咬坏的也多—-卖木桶的生意兴隆,赚钱;学会转换思考,需要不断换位,以假设状况为前提,进行正面刺激,换角度思考问题,如一老农西瓜地的瓜经常被盗,他采取了许多方法来惩治,写了许多标语,违者罚款,但收效甚微,一智者路过,提醒他换个角度,从惩罚改为谁看见有人偷西瓜,奖励多小钱,发动了众人的积极性,取得了很好的效果。需要信息组合,进行期望点或缺点列举。如在给企业策划品牌命名时,可以根据产品所提供的利益和主要功能、主要成份、外观特点命名;根据产品创始人或企业名命名;根据名人、名地或名胜命名;根据外语读音命名;根据数字或无意义的杜撰文字命名;根据激发积极联想的文字命名等等。

  策划的创意与创新可以来自传统管理故事的思考,如对龟兔赛跑的故事创新;对木梳卖给和尚的故事创新;对固定路径的依赖;高原现象;不拉马的士兵;短板理论、破窗理论、粘鱼效应等等;策划需要借势和造势;需要利用公关事件;策划需要吸引眼球的注意力;需要获取影响效应;如一小说的作者为了推广其所写的小说,在许多杂志上刊登了征婚启示,号称一身价过亿的富豪,想征婚,要求女主人应该向其小说中所描述的主人公那样,具有相应的标准,使该小说很快在市场上小说一空。

  策划人创意与创新能力的培育,关键在于思维和思路,在于对资源的整合和换位思考,在于寻求差异化和借助外部力量,在于思路的转变和思维的创新。如市场理念创新,从满足需要到引导和创造顾客需要;市场定位观念方面从传统的寻找商品用户转向追寻企业免受竞争的“知识经营”领域;市场占有观念从注重市场份额转向追寻提高客户价值份额和企业主导市场的能力;竞争观念从你死我活到共生共赢与竞合;人才观念从注重培养专业人才转向培养有创造性的复合型人才;营销资源观念从以内部资源创造营销效益转向利用内部和外部资源创造营销效益。正如有人说的那样,创意的培育要经历“四境”,一是准备过程,昨夜西风凋碧树,独上高楼,望尽天涯路;二是酝酿过程,衣带渐宽终不悔,为伊消得人憔悴;三是顿悟过程,众里寻他千百度,暮然回首,那人却在灯火阑珊处;四是验证过程,需要大胆假设,小心求证。

  总之,策划人是凭借脑力进行思考和生存的,策划人凭的是阅历和创新能力,凭借的是敏锐的洞察与分析能力。随着社会的不断向前发展,策划行业会面临来自不同方面的竞争,竞争的日趋激烈,策划正在朝区域化、专业化的方向发展,策划人因相应地进行转型与重新定位,而且随着客户整体素质和实力地提升,门槛会越练越高,希望策划行业中杜绝李鬼与李逵并存、滥竽充数的现象,少一些欺骗,多务实和创新,真正提升客户的价值,创造价值,让生活因策划而更加精彩。

作者:王唤明

web交互界面易用性设计和验收的指导性原则

. 输入控件的自动聚焦和可用键盘切换输入焦点

使用JavaScript实现页面加载完成后立即自动聚焦(focus)到第一个输入控件。可用TAB键(IE缺省实现)或方向键切换聚焦到下一个输入控件。

  输入控件指WEB页面表单(&lt;form&gt;)中显式的,需要用户进行修改、编辑操作的表单元素。对于这些控件,如果没有自动聚焦操作,不可避免的出现一次用户鼠标定位操作(如果用户此前处于键盘输入操作状态或鼠标定位后需要进行键盘输入操作,实际上是键盘鼠标切换操作)。如果鼠标定位后需要进行键盘输入操作,如果不能键盘切换输入焦点,那么不可避免的在切换输入焦点时需要反复的键盘鼠标切换操作,这是很繁琐的。

  如果实现了页面加载完成即自动聚焦到第一个输入控件,并且可以键盘切换输入焦点标定位操作,那么对于用户来说整个页面的输入操作可能都不需要鼠标操作,或次数较少,这是一种便利。毕竟频繁的键盘鼠标切换操作是比较累人的。

  对于有输入栏的对话框或网页,在不干预的情况下就应将当前控制焦点定位在待输入的输入栏上;如果输入栏在一般情况下不需要更改其中的内容,则应直接将焦点定在&ldquo;确定&rdquo;按钮上;在几个输入栏之间应支持tab,shift+tab切换操作,&ldquo;确定&rdquo;和&ldquo;取消&rdquo;应该是切换操作的终点,与具体所在位置无关。

  2. 可用Enter(或Ctrl+Enter)键提交,确保和点击提交按钮的效果是相同的

  不要在提交按钮上加入onClick=&rdquo;&hellip;&rdquo;这样的JavaScript代码。

  用Enter键提交页面是原则1的自然延伸,而且这也是浏览器所缺省支持的。只所以单独列出来是因为实际上有些设计者设计的页面不能达到这种效果,结果导致使用Enter键提交和点击&ldquo;确定&rdquo;按钮提交带来的效果不一样。大部分情况下是设计者在&ldquo;确定&rdquo;按钮上加入了onClik=&rdquo;&hellip;&rdquo;这样的代码,通过点击&ldquo;确定&rdquo;按钮后,会执行一段JavaScript代码,比如对某些hidden类型的input元素设值。而使用Enter键提交时就不会执行这段代码。

  正确的做法是把这段代码移到表单标签&lt;form&gt;中,以onSubmit=&rdquo;&hellip;&rdquo;属性引入。

  对于&lt;textarea&gt;表单元素,它会消耗Enter键,因此会使得Enter键提交失效。可以引入JavaScript代码捕捉Ctrl+Enter复合键,一旦捕捉到即执行表单的submit()方法。对于需要频繁提交的场合,比如BBS上,这种代码是很有必要的。

  3. 鼠标动作提示和回应

  对用户的鼠标定位操作,当移动到可响应的位置上时,应给予视觉或听觉的提示。

  动作回应的最简单形式就是鼠标ICON变成手状。浏览器只对具有href属性的HTML标签会自动进行这种变换ICON的行为。对于没有href属性(或没有设置href属性)的标签,可以通过JavaScript设置style属性的cursor为hand。

  目标区域发生变化是更为主动的响应形式。当鼠标指针移到目标区域,此时指针图形改变或文字颜色发生改变均能较大的减轻用户搜索定位目标区域的注意力负担。在按钮上增添直观的图形,尽可能的增大按钮面积;按钮间保持适当的距离,太近增加了用户区别它们之间界限以防误操作的负担,太远增加了用户搜索定位按钮的负担。

  4.尽可能早的在客户端完成输入数据合法性验证

  输入数据的合法性检验应该在客户端使用JavaScript进行验证。除非验证只能在服务器端完成,否则验证工作应在最早能完成的情况下进行。

  在客户端完成数据合法性验证,可以避免一次服务器请求和回复通讯,这种通讯是需要用户等待的,如果用户等待很长时间后从服务器返回的结果提示出现的错误是在输入时即可发现的,那么这种设计就是不友好的。诸如密码长度限制,用户名允许字符限制等等,显然应该在客户端提交前就应该进行验证。

  5. 根据应用场景决定在表单页面和提交后返回页面间是否使用中间过渡页面

  根据应用场景,决定是否显示接收表单页面(表单页面和提交后返回页面间的中间过渡页面),以及使用何种方式显示接收表单页面。

  表单页面和接收表单页面是大部分WEB交互操作赖以实现的配合模式。关于表单页面和接收表单页面的相互关系的设计,要做如下几个方面的考虑。

  一,对于需要频繁操作的场合,从操作便利和快捷性出发,尽可能的减少服务器和客户端交互次数,应该避免使用中间过渡页面。提交完毕直接返回原来的表单页面或默认页面。在这种情况下要考虑到数据安全和可恢复性。

  如果因为用户输入的数据不合格,需要重新输入,那么,去除中间页面,把错误信息直接显示在原表单页面上的设计方式,将是最简洁的处理方式。用户只需要根据错误提示进行更正即可。当然这样做稍微增加了编程负担。在表单接收页面上需要包含原表单页面的内容,而且输入数据项都必须用服务器端代码或客户端JavaScript设置成用户输入的值。为了开发快捷,可以这样做:表单页面和接收表单页面用同一个服务器端脚本页面实现。这个页面按如下流程完成原来两个页面的工作:

页面脚本初始化

检查&ldquo;提交&rdquo;变量是否设置
┠已设置,做数据验证
┃ ┠验证通过-&gt;业务逻辑处理-&gt;使用包含页面方式或重定向方式返回到特定页面&nbsp;
┃ ┗验证不通过-&gt;保存用户输入的数据-&gt;退出表单提交处理到表单页面流程中
┗未设置,做表单页面流程,如有来自提交流程中产生的用户输入数据,则显示出来

  其中,使用包含页面方式返回到特定页面可以避免一次客户端重定向过程,比客户端重定向过程还要快捷和稳定一些。但是有些情况下因为代码变量冲突或其他原因,使用包含页面方式可能并不方便,这时候可以使用服务器端重定向技术,在ASP里是Server.Transfer方法,在Java Servlet里是RequestDispatcher.forward()方法。不要使用Response.Redirect或者HttpServletResponse.sendRedirect()这种客户端HTTP重定向方法。不使用中间过渡页面也就意味着用户不能后退浏览原先已经填好的表单页面,因为使用的是同一个URL。所以在验证不通过情况下保存用户输入的数据就是必不可少的。

  不使用中间过渡页面带来的另一个问题就是使用包含页面方式或服务器端重定向方式返回会使得URL和页面内容不能一一对应。对于用户可能会直接用这个URL(会收藏这个URL)访问返回页面的情况,他会发现实际上到达的是表单页面,不是他想要的那个返回结果页面。所以,去除中间过渡页面,确实会带来URL和内容含混不清的情况,因而不适合需要URL和页面内容一一对应的场合。

  二,从技术角度考虑,使用中间过渡页面能保证URL和页面内容一一对应,简化页面开发工作。

  为了保证页面内容总是和固定的URL联系起来,必须使用客户端重定向:

提交 业务逻辑处理 (中间过渡页面)
表单页面――――-&gt;接收表单页面―――――――――&gt;显示处理结果―――&gt;客户端重定向到特定页面

  客户端重定向分几种情况:1,使用HTTP Header重定向,Location:http://www.netall.com.cn,这种定向是最快的,在窗口一片空白的情况下就迅速访问(GET)另一个页面。这种方式实际上不能显示处理结果,只能说是向第一种快速重定向方式的一种折衷处理;2,HTML标签刷新,&lt;META HTTP-EQUIV=&quot;Refresh&quot; CONTENT=&quot;5;URL=http://www.netall.com.cn&quot;&gt;,这种定向比较友好,在这个页面加载完毕后访问另一个页面。很多设计者把这个作为一个技巧使用,在载入一个大页面前放置一个缓冲页面以避免用户乏味的等待;3,JavaScript重定向。由于是用代码控制重定向,可以做的更灵活。比如根据用户习惯,控制操作完毕后的转向流程。4,被动式的重定向。在页面上放置按钮或链接,由用户手动决定返回到特定页面。这种情况适合于处理结果的显示页面包含相当多的信息,需要用户仔细浏览,而决定下一步的操作。

  在使用中间过渡页面的情况下,不能再使用页面过期失效了。否则一旦出现错误,需要用户重新输入表单数据,用户就不能用后退按钮恢复此前填写的表单数据了。除非设计者有意禁止这种恢复。

  6. 防止表单重复提交处理

  对提交按钮点击后做变灰处理避免在网络响应较慢情况下用户重复提交同一个表单。使用页面过期失效避免用户后退浏览重复提交表单。

  有些复杂的应用会导致需要较长时间的等待才会返回处理结果。而在较慢的网络环境中,这种情况更是频繁发生。焦急等待的用户往往会重复点击提交按钮。这种情况是设计者所不希望看到的。

  使用JavaScript在点击提交按钮后使按钮失效变灰是一个最直接的办法(根据原则2这段代码应该放在&lt;form&gt;标签里onSubmit=&rdquo;&hellip;&rdquo;做)。此外,在表单页面上,用服务器端脚本设置HTTP Header的Expires为立即过期可以保证用户没办法使用后退浏览恢复表单页面。注意这样做的代价可能是用户辛辛苦苦填写很长的内容,结果一旦操作失误就没法恢复。所以应该避免在包含&lt;textarea&gt;表单元素的页面上使用页面过期失效。

  应该说,更严格的方法是,服务器端脚本就应该具备抵抗重复提交的能力。例如,为这个表单分配一个唯一ID或一个使用一次即失效的验证码。此外,这个表单处理还应具有事务性质,如果表单不被接受,所做的改变还是能恢复的。在金融应用场合,重复提交同一笔交易是肯定不被允许的。能在重复提交中获利的一方总是会想办法绕过浏览器的限制,所以不能依赖于客户端的技术。

  7. 页面链接是打开新窗口、使用原窗口还是弹出窗口的原则

  一般而言,首页上链接可以使用target=&rdquo;_blank&rdquo;属性打开新窗口,而其他页面上的链接都应使用原窗口或弹出窗口。如果链接页面内容相对原页面来说不重要,是附属性质的,可以使用弹出窗口方式。

  一般情况下应该使用原窗口,把是否保留原窗口内容的权利留给用户。除非设计者相信原页面是如此重要,在用户发出点击指令后还有使用上的价值,以至于不能被随便更新或覆盖。一般来说,只有首页才会处于这样一个地位,用户在首页上打开一个链接后,一般还会在这个首页上去打开另一个链接。比如首页包含极多链接的门户网站,或者搜索引擎的搜索结果页面。Google.com以前的搜索结果页面上的链接是使用原窗口的,后来他们意识到用户会反复使用这个页面,而改成打开新窗口了。一般的网站如果首页链接不多,就不必使用新窗口,这是用户友好的设计原则。

  上述情形的一个极端情况就是新页面内容比起原页面内容的重要性差很多,以至于都未必需要打开一个新页面。这时候使用弹出窗口比较合适。用JavaScript弹出窗口有好几种:一个是window.open()函数。这里有个技巧。应该使用window.open()先打开一个空白窗口,再使用location.replace()用目标页面替换。这样做可以避免在打开新页面的过程中导致原页面失去响应。Window.open()将打开一个新的浏览器窗口进程,因此资源消耗比较大。另一个是由微软DynamicHTML规范中扩充的方法createPopup()。createPopup()可以创建无边框的弹出窗口,消耗系统资源较小。还有一个就是用页面中隐藏的层&lt;div&gt;来模拟一个弹出页面。后两种可以使用JavaScript代码填充弹出窗口内容。如果需要下载网页作为其内容的话,需要微软DynamicHTML规范中的&lt;download&gt;标签。

微软资深经理人的网站项目管理经验

这是微软资深项目经理人Stephen Maguire的项目管理经验。软件开发和网站开发有极其相似的地方,我们可以从中学习领会许多知识。

第一章 有效团队的基础

1、专心改善产品

公司付工资给设计师,要他们在合理的时间开发出品质精良的网站,但是设计师们的时间却经常被其它事情占用了。

典型的情况是设计师要花大量的时间准备会议,参加会议,读写开会记录和进度报告,还有回复email等等,这些事情都不能改善网站的工作,虽然其中一些是设计师自己主动做的,但更大一部分是项目经理下的命令。

虽然项目经理的本意是好的,但是却违背了项目经理的基本守则:项目经理的任务是努力消除设计师工作上的一切障碍,让设计师权利专注在真正重要的工作上—网站开发。

这不是震惊世界的发现,只是简单的道理,但是有多少项目经理确实做到呢?

2、排除干扰

如果你希望团队在期限之内完成网站,就必须尽可能排除一切不必要的工作。在你分派工作给组员前,请问问自己,这件工作真的有必要让大家做吗?身为项目经理,必须时刻问自己一个问题: “我努力的目的究竟是什么?”

常见的就是让组员写报告。一天8小时工作时间,很可能4个小时花在了写报告上。而正常的开发工作却不得不加班做。

请不要误解我的意思,我并不是说不需要进度报告,只是提醒项目经理们,不要过分注重“项目流程”,而忽略了真正的产品—-你的网站。我的一点心得是:用一个新的办法了解进度,容易写,而且不花时间。

1)当有设计师完成一个功能(子项目),就发一个内部email给大家;

2)当项目进度可能落后,就和我私下交流,讨论解决的办法。

3、明确目标

什么样的目标是明确的目标呢?其实并不一定是博大精深的,只要足够详细,能够保证项目向正确的方向进行就可以。通常只要项目组长花几小时,或者几天时间就可以制定一个详细的项目目标。例如本站:

目标1: 建立一个以网站项目管理为主题的网站。评价:目标已经明确主题,但还是不够详细。

目标2:为网站项目管理爱好者提供一个交流的平台。评价:目标定位了服务对象和主要功能。但是并没有体现我们建立网站的深层目的。

目标3:为网站项目管理爱好者提供一个学习交流,并能够共同制定详细规范的平台。评价:明确的目标,指出了服务对象,最主要的功能和网站本身的目的。

在目标确定后,我们就坚持这个大方向,凡是有利于目标实现的最先完成,比如:论坛,规范文章。与目标无关或关系不大的,可以不做或者推迟做,比如人才交流,漂亮的界面等。

4、设计的优先考虑

我们要建立以下基本观念:项目目标引导项目的方向,而设计的考虑顺序影响设计的过程。

每个项目的具体情况不同,考虑的优先顺序也回不同,一般来说,程序设计考虑的优先级表为:

1)尺寸大小(size)

2)速度

3)安全性

4)可测试性

5)容易维护

6)简洁

7)再用性

8)可移植性

除了优先考虑顺序外,你还应该建立各项考虑点的质量规范。如果事先能够决定最合适的优先考虑顺序,并建立质量规范,团队就不会浪费时间,网站的整体风格就会比较一致。

第二章 有效的作业方式

1、什么时候修改错误

微软的经验是:(1).bug越晚清除,时间花得越多; (2).在开发过程中立刻除虫,可以让您早些学到经验,然后不会犯同样的错误;(3).如果能够保证没有任何错误,您就能比较准确的估出项目的完成时间。 所以,设计师应该把找错误当成一件重要的事情,不要为任何理由而耽误。

2、email的时间陷阱

回复email要分批做,早上一上班,中午休息时间,或者是下班前看一下都可以,但不要有事没事都不停的看email。

3、方法让大家分享

身为主管,你应该鼓励组员提出改进工作效率的建议。引导组员思考的方法也很重要。比如,下面两个问题:

a.为什么进度总是一再落后?

b.有什么办法可以避免将来再发生进度落后?

第一个问题可能的答案是:互相依赖的工作太多,工具太难用,老板是个白痴等等;第二个答案可能是:减少互赖性的工作,购买更好的工具,与老板加强沟通。

两个问题的方向不同,第一个是探究原因,导引出抱怨;第二个是未来改进的方法,导引出解决办法。

问题越精确,问题越有力,对项目目标的实现就越有益,让我们再看三个问法:

a.如何保持每次都如期完成项目?

b.如何在不加班的前提下,如期完成项目?

c.如何在不加班,也不增加人手的前提下,如期完成任务?

第三个问法,就迫使大家来点真正有创意的思考和认真检讨工作本身值得改进的地方了。一次比一次更精确的问题,可以刺激思考过程,激发更有创意的答案。

4、无意义的惩罚

惩罚是一种心理上的负强化作用,惩罚是对员工的责骂,训斥与威胁,就象鞭打马匹使它服从主人的命令。这种管理手段是该受谴责的,如果主管们的用意是希望组员因此而工作更努力的话,就大错特错了。这种责骂只会激起组员心中的愤怒,羞恼和沮丧。实际上,往往这些项目的问题都出在管理方面,目标不明确或者野心太大,设计师只是倒霉的遇上了差劲的主管,其实他们的能力不比其他项目的设计师差。因此放弃责骂吧,责骂只会让项目更糟,绝对没有任何改善的效果。

第三章 保持进度

即使最顺利的项目,也无法完全按照计划执行,但是,如果你放任计划随意进行,有一天你猛然发现项目脱轨太远,来不及完成。项目就象一枚瞄准月球的火箭,只要有一点点不够精确,到时候就无法命中目标,差之毫厘,失之千里,实在不可不慎重。聪明的主管懂得这个道理,他们会经常注意项目的精度,随时修正方向,保持项目不偏离计划进行。本章将介绍一些很有效的策略,帮助项目保持进度。

1、向前看

我一直相信,项目之所以脱轨,主要原因在于人们没有认真思考如何使项目保持进度,顺利进行。如果没有未雨绸缪,只是坐等问题发生,到那时候就太迟了。一个月前没有花30分钟思考这个问题,现在就可能要浪费几小时或几天的时间去修正。这就是所谓的“被动工作”。

解决这种被动工作的方法,就是化被动为主动,事先发掘潜在的问题,并设法避免。有很多方法和技巧可以训练自己“向前看”,但总结起来不过是一句简单的要决:定期暂停手边的工作,然后往前思考,随时做必要的修正,以避免未来的大障碍。

我已经有十年以上的习惯,每天花10到15分钟思考下列问题,并且列出答案: 有什么事情是我今天能做,而且可以帮助项目在未来几个月内顺利进行的?

2、明确定义需求的范围

人们在开口要求的东西未必是他真正想要的,处理他的要求之前,请务必确定他究竟想要做什么。

在网站项目开发中,经常会遇到客户或者领导层提出一些希奇古怪的需求。一次,首席设计师惊慌失措的跑来找我,告诉我麻烦来了,客户对新设计的界面不满意,要求按照某个著名网站一摸一样的设计。如果真的那样做,需要重新花一个星期才能做出来,可是目前离期限的时间已经很短了。听了他的陈述后,我必须承认如果真得那样做,我们的进度就完蛋了,同时我也很好奇,为什么客户会有这样的要求,所以在我答复他们做还是不做之前,请客户经理去了解一下这个需求的原因。不一会儿,客户经理笑嘻嘻地回来了。

“他们只是看中了那个网站的动态下拉菜单,觉得那样比较吸引人”

呵呵,我知道他在笑什么了,这样的动态菜单我们其实早就有现成的模板了,只要将它替换现有的设计就可以了。而我们的设计师不清楚客户的喜好而已。

大部分客户在提出需求时都不解释原因,这种情况太普遍了,甚至你的管理层也会发生这种情况。如果你从他们的请求中无法看出他们的目的,你可以反问他们,在还没有弄清楚究竟想要做什么之前,不要贸然答应,宁可拒绝他们的要求也不要浪费这种时间。

3、就是说不

当遇到客户或上级的无理需求,项目经理往往会忍气吞声的同意他们的要求。迫于某些压力,主管们宁可宁事息人,也不愿意为了整个产品或自己的团队坚持最佳的选择。

有时候,对方的请求也可能是非常合理的,你也想同意,但是因为你的日程排满了,实在爱莫能助,您也只好对他们说“不”。然而,在我的经验中,很多主管为了避免冲突,仍然会同意这样的请求,只是不知道该如何如期完成这些过多的工作,只是想到时候再说吧,船到桥头自然直,事实上事情很少这么容易——船上若是载了太多的货,就是船身直了也过不了桥啊。

这些主管不了解,勉强接下自己不可能完成的任务,实在是一长痛代替短痛的做法,到时候无法如期完成,倒霉的是整个团队因此必须加班工作。所以,最好的办法还是老老实实拿您的日程表,与客户或上级说明自己心有余而力不足的情况,设法安排一个折中的日程或工作内容。想想这要比现在无条件答应请求而最后食言的结果要好的多。

4、你无法让每个人都满意

身为项目主管,你必须明白这个道理:如果您希望每个人都满意,最后您会焦头烂额,什么事都做不成。

记住:不要为了讨好别人而伤害工作进程,您永远要根据自己的目标,做适当的决策。

同样,对待上级的建议您也应该考虑后再决策,不要盲从。应该以项目目标为最优先的考虑。我不是主张反抗权威,而是强调:上级也是人,一样可能犯错,他们的建议不一定是最好的,如果你想做一名出色的主管,您必须非常认真的衡量所有的建议,不论是谁提出的,您都得确定其符合项目目标才能采纳。

如果上级要求您做一件事,而您认为不妥,那您应该在着手进行之前向上级说明您的想法,也许上级回同意你的想法而放弃他的建议,也许,上级会赞许你的想法,但仍请你考虑他的意见,不论结果如何,起码经过沟通对彼此都有帮助。

记住:是你在为项目负责,不要让任何人的建议阻碍项目的进行,包括上级的建议。

想确保项目按计划进行,其关键就在于项目经理完全明白该做什么,并且不让该做的事受到不当的干扰。

google adsense的一些准则

google adsense产品的一些原则

1.永远不要作弊(太老土了)
2.每个申请帐号的地址只能对应一个人名,用家里人身份证申请的,注意了.
3.不要试图在同一台机器上面登录多个帐号.身在外地的站长,想看数据的时候忍忍吧,千万别用站长朋友的机器登录,小心连坐.建议使用报表功能把多个帐号的收入每天发送到指定邮箱.
4.保持自己所用机器的干净,不要点击任何google的广告.
5.如果非要点几个广告,登录几个帐号,请先清理机器上面所有浏览器的临时文件和cookie,并且彻底更换IP
6.互点必死
7.用干净的网站注册帐号,google不在乎你是否把广告放在这个网站上.
8.网站有色情内容100%被封.版权内容可以在你认识google的人的情况下做.
9.收入上升过快必死
10.google如果要k号,永远跟作弊无关.google只在乎效果是否好,并不在乎你是否作弊(其实跟第一条并没有冲突,可以慢慢理解)
11.google投放出来的所有广告,均会监控转化率,转换率达不到一定标准一定被k号.就算不被k号,也会被降权.(具体比例就不说了)
12.google近来在拼命推一个产品,叫做Google Analytics,想必很受站长们的欢迎.大家知道这个东西的主要作用是什么吗?k号.说白了就是用来监控广告的转化率和监控你是否作弊.嘿嘿,怕了吧.

google adsense的一些优化规则
1.目前国内效果最好的广告样式是小方块
2.每个页面上面的广告个数不要超过3个.google广告的价格是按照出现时间递减.也就是说,最先出来的广告价格最高,然后每个价格越来越低
3.google广告可以跟其他广告(比如百度)等放同一个页面.

IIS 占用 CPU %问题排查方案

有时候辛辛苦苦写个网站,挂到服务器上一看,CPU给百分百了,这种问题百分之八九十都是因为代码写有问题,而不是因为系统设置的问题,这种问题也比较难排查。但是结合一些工具也可以找到原因的,关于windbg的使用,好像有本关于.net调试的书,大家有兴趣可以看看,网上也有一些帖子,但关于ANTS Profiler的帖子就比较少了,大家也可以下载试用版来帮助解决问题

1 准备日志
1.1 用perfmon添加计数器日志,添加如下计数器

ASP.NET:所有计数器
Memory:所有计数器
Process:所有计数器和所有实例
Processor:所有计数器和所有实例
Thread:所有计数器和所有实例
Web service:所有计数器和所有实例

1.2 间隔改成1,单位改成秒

1.3 用鼠标右键单击这个日志名,然后单击开始。确保日志捕获了处理器利用率猛增至 100% 的那段时间内的所有数据。

2  抓Dump
2.1 用IIS Diagnostics Toolkit工具找出占用CPU高的w3wp进程ID

2.2 用windbg执行以下命令adplus –hang –p pid并抓取dump

3 检查日志
3.1 识别哪一个进程消耗了大部分的 CPU 时间

用perfmon打开准备好的日志文件,用鼠标右键单击图表,然后单击添加计数器。在添加计数器对话框中,从性能对象列表中选择 Process。选择从列表中选择计数器,然后从此列表框中选择 %Processor Time。选择所有实例,单击添加,然后单击关闭。

这将为我们提供所有处理器及其 CPU 使用情况的列表。现在您需要查清哪个进程引起了 100% 的 CPU 问题。

确保选中了突出显示工具按钮(黄色灯泡图标)。现在您可以滚动这些计数器,将除最接近 100% 标记的那个进程之外的所有进程全部删除。确保只选择了那些与您有关系的计数器。例如,如果您正在调试 100% 的 CPU 利用率的问题,您也许应该查找w3wp、inetinfo、其它的脱机处理的 COM 程序包/应用程序 (MTX.EXE/DLLHOST.EXE) 或者 IIS 应用程序。

3.2 找出该进程内部的那些在出现 100% 的 CPU 问题时仍然活动的线程实例

一旦您在进程级将问题隔离出来,您就可以将注意力集中在该进程内部的那些在出现 100% 的 CPU 问题时仍然活动的线程上,并试着隔离引起问题的那个线程。为此,我们添加更多的计数器来显示该进程中所有线程的 CPU 使用情况。对于本例而言,就是为w3wp进程(假设它占用CPU最高)中的所有线程添加计数器。用鼠标右键单击图表,然后单击添加计数器。在添加计数器对话框中,从性能呢个对象列表中选择 Thread。选择从列表中选择计数器,然后从列表框中选择 %Processor Time。选择 从列表中选择实例,然后选择以 w3wp/* 开头的所有实例。单击添加,然后单击关闭。

这时,图表中显示在w3wp进程中的所有线程的 CPU 使用情况。

现在可以滚动计数器,将除最接近 100% 标记的那个线程以外的所有线程全部删除。这样我们就准确地找到了引起问题的那个线程(假设它的线程实例ID为12)。

3.3 找出导致CPU占用100%的线程ID

我们只保留实例ID 为12的线程(上一步操作留下的那个线程),它占用了最长的 CPU 时间。现在必须找出这个线程的线程 ID,然后在 WinDBG 中找到这个线程并对它进行调试。

要找出线程 ID,请用鼠标右键单击图表,然后单击添加计数器。在添加计数器对话框中,从心能对象列表中选择 Thread。选择从列表中选择计数器,然后从此列表框中选择 ID Thread。选择从列表中选择实例,然后选择实例w3wp/12(看具体情况而定)。单击添加,然后单击关闭。

这样我们就得到了引起问题的那个线程的 ID。选择 ID Thread 计数器。记录该计数器的最后一个值、最大值、最小值和平均值。通常这四个数是相同的。记录这个值(比如说1460),并切换到 WinDBG 应用程序。

4  找出导致CPU占用100%的相关代码
4.1 打开windbg,点击菜单File/Open Crash Dump,选择第二步用Adplus抓的dump文件

在 WinDBG 的 View 菜单上,单击 Processes and Threads。这将显示在出现 100% 的 CPU 问题时在w3wp进程内部运行的线程的一个列表。查找您在性能监视器中记录的线程 ID 号(3.3步中找到的线程ID,这个ID是十进制的,用calc换算成16进制标识)。如果在列表中找到此 ID 号(16进制),则单击选中它。单击 OK。

在 View 菜单上,单击 Call Stack。这时显示引起问题的那个线程的堆栈。该堆栈将有问题的方法隔离出来。一旦我们找到这个方法,我们就可以返回原代码,查看是哪行代码引起这个问题的。