[LoadRunner]LR函数小全

给出一部分常用的LoadRunner函数,供大家参考。
LR函数:
lr_start_transaction 为性能分析标记事务的开始
lr_end_transaction 为性能分析标记事务的结束
lr_rendezvous 在 Vuser 脚本中设置集合点
lr_think_time 暂停 Vuser 脚本中命令之间的执行
lr_end_sub_transaction 标记子事务的结束以便进行性能分析
lr_end_transaction 标记 LoadRunner 事务的结束
Lr_end_transaction("trans1",Lr_auto); lr_end_transaction_instance 标记事务实例的结束以便进行性能分析
lr_fail_trans_with_error 将打开事务的状态设置为 LR_FAIL 并发送错误消息 lr_get_trans_instance_duration 获取事务实例的持续时间(由它的句柄指定) lr_get_trans_instance_wasted_time 获取事务实例浪费的时间(由它的句柄指定) lr_get_transaction_duration 获取事务的持续时间(按事务的名称)
lr_get_transaction_think_time 获取事务的思考时间(按事务的名称) lr_get_transaction_wasted_time 获取事务浪费的时间(按事务的名称)
lr_resume_transaction 继续收集事务数据以便进行性能分析
lr_resume_transaction_instance 继续收集事务实例数据以便进行性能分析 lr_set_transaction_instance_status 设置事务实例的状态
lr_set_transaction_status 设置打开事务的状态
lr_set_transaction_status_by_name 设置事务的状态
lr_start_sub_transaction 标记子事务的开始
lr_start_transaction 标记事务的开始
Lr_start_transaction("trans1"); lr_start_transaction_instance 启动嵌套事务(由它的父事务的句柄指定)
lr_stop_transaction 停止事务数据的收集
lr_stop_transaction_instance 停止事务(由它的句柄指定)数据的收集
lr_wasted_time 消除所有打开事务浪费的时间
lr_get_attrib_double 检索脚本命令行中使用的double 类型变量
lr_get_attrib_long 检索脚本命令行中使用的 long 类型变量
lr_get_attrib_string 检索脚本命令行中使用的字符串
lr_user_data_point 记录用户定义的数据示例
lr_whoami 将有关 Vuser 脚本的信息返回给 Vuser 脚本
lr_get_host_name 返回执行
Vuser 脚本的主机名
lr_get_master_host_name 返回运行 LoadRunner Controller 的计算机名
lr_eval_string 用参数的当前值替换参数
lr_save_string 将以 NULL 结尾的字符串保存到参数中
lr_save_var 将变长字符串保存到参数中
lr_save_datetime 将当前日期和时间保存到参数中
lr _advance_param 前进到下一个可用参数
lr _decrypt 解密已编码的字符串
lr_eval_string_ext 检索指向包含参数数据的缓冲区的指针
lr_eval_string_ext_free 释放由 lr_eval_string_ext 分配的指针
lr_save_searched_string 在缓冲区中搜索字符串实例,并相对于该字符串实例,将该缓冲区的一部分保存到参数中
lr_debug_message 将调试信息发送到输出窗口
lr_error_message 将错误消息发送到输出窗口
lr_get_debug_message 检索当前消息类
lr_log_message 将消息发送到日志文件
lr_output_message 将消息发送到输出窗口
lr_set_debug_message 设置调试消息类
lr_vuser_status_message 生成带格式的输出,并将其写到 ControllerVuser 状态区域
lr_message 将消息发送到 Vuser 日志和输出窗口 lr_load_dll 加载外部 DLL
lr_peek_events 指明可以暂停 Vuser 脚本执行的位置
lr_think_time 暂停脚本的执行,以模拟思考时间(实际用户在操作之间暂停以进行思考的时间) lr_continue_on_error 指定处理错误的方法 lr_continue_on_error (0);lr_continue_on_error (1);
lr_rendezvous 在 Vuser 脚本中设置集合点
TE_wait_cursor 等待光标出现在终端窗口的指定位置
TE_wait_silent 等待客户端应用程序在指定秒数内处于静默状态
TE_wait_sync 等待系统从 X-SYSTEM 或输入禁止模式返回
TE_wait_text 等待字符串出现在指定位置
TE_wait_sync_transaction 记录系统在最近的 X SYSTEM 模式下保持的时间

WEB函数列表:
web_custom_request 允许您使用 HTTP 支持的任何方法来创建自定义 HTTP 请求
web_image 在定义的图像上模拟鼠标单击 web_link 在定义的文本链接上模拟鼠标单击 web_submit_data 执行“无条件”或“无上下文”的表单
web_submit_form 模拟表单的提交
web_url 加载由“URL”属性指定的 URL
web_set_certificate 使 Vuser 使用在 Internet Explorer 注册表中列出的特定证书 web_set_certificate_ex 指定证书和密钥文件的位置和格式信息
web_set_user 指定 Web 服务器的登录字符串和密码,用于 Web 服务器上已验证用户身份的区域 web_cache_cleanup 清除缓存模拟程序的内容
web_find 在 HTML 页内搜索指定的文本字符串
web_global_verification 在所有后面的 HTTP 请求中搜索文本字符串
web_image_check 验证指定的图像是否存在于 HTML页内
web_reg_find 在后面的 HTTP 请求中注册对 HTML源或原始缓冲区中文本字符串的搜索 web_disable_keep_alive 禁用 Keep-Alive HTTP 连接
web_enable_keep_alive 启用 Keep-Alive HTTP 连接
web_set_connections_limit 设置 Vuser 在运行脚本时可以同时打开连接的最大数目 web_concurrent_end 标记并发组的结束
web_concurrent_start 标记并发组的开始
web_add_cookie 添加新的 Cookie 或修改现有的 Cookie
web_cleanup_cookies 删除当前由 Vuser 存储的所有 Cookie
web_remove_cookie 删除指定的 Cookie
web_create_html_param 将 HTML 页上的动态信息保存到参数中。(LR 6.5 及更低版本) web_create_html_param_ex 基于包含在 HTML 页内的动态信息创建参数(使用嵌入边界)(LR 6.5 及更低版本)。
web_reg_save_param 基于包含在 HTML 页内的动态信息创建参数(不使用嵌入边界) web_set_max_html_param_len 设置已检索的动态 HTML 信息的最大长度
web_add_filter 设置在下载时包括或排除 URL 的条件
web_add_auto_filter 设置在下载时包括或排除 URL 的条件
web_remove_auto_filter 禁用对下载内容的筛选
web_add_auto_header 向所有后面的 HTTP 请求中添加自定义标头
web_add_header 向下一个 HTTP 请求中添加自定义标头
web_cleanup_auto_headers 停止向后面的 HTTP 请求中添加自定义标头 web_remove_auto_header 停止向后面的 HTTP 请求中添加特定的标头
web_revert_auto_header 停止向后面的 HTTP 请求中添加特定的标头,但是生成隐性标头 web_save_header 将请求和响应标头保存到变量中
web_set_proxy 指定将所有后面的 HTTP 请求定向到指定的代理服务器
web_set_proxy_bypass 指定 Vuser 直接访问(即不通过指定的代理服务器访问)的服务器列表 web_set_proxy_bypass_local 指定 Vuser 对于本地 (Intranet) 地址是否应该避开代理服务器 web_set_secure_proxy 指定将所有后面的 HTTP 请求定向到服务器
web_set_max_retries 设置操作步骤的最大重试次数
web_set_timeout 指定 Vuser 等待执行指定任务的最长时间
web_convert_param 将 HTML 参数转换成 URL 或纯文本
web_get_int_property 返回有关上一个 HTTP 请求的特定信息
web_report_data_point 指定数据点并将其添加到测试结果中
web_set_option 在非 HTML 资源的编码、重定向和下载区域中设置 Web 选项 web_set_sockets_option 设置套接字的选项

LoadRunner函数中文翻译系列之一--Action

2009年09月26日 星期六上午 09:45

web_url

语法:
Int Web_url(const char *name, const char * url, <Lists of Attributes>, [EXTRARES,<Lists of Resource Attributes>,LAST)
返回值
成功时返回LR_PASS (0),失败时返回 LR_FAIL (1)。
参数:
Name:VuGen中树形视图中显示的名称,在自动事务处理中也可以用做事务的名称。
url:页面url地址。
List of Attributes
EXTRARES:分隔符,标记下一个参数是资源属性的列表了。
List of Resource Attributes
LAST:属性列表结束的标记符。
说明
Web_url根据函数中的URL属性加载对应的URL,不需要上下文。
只有VuGen处于URL-based或者HTML-based(此时A script containing explicit URLs only选项被选中时)的录制模式时,web_url才会被录制到。
可以使用web_url 模拟从FTP服务器上下载文件。web_url 函数会使FTP服务器执行文件被真实下载时的操作。除非手工指定了"FtpAscii=1",下载会以二进制模式完成。
在录制选项中,Toos—Recording Option下,Recording选项中,有一个Advanced HTML选项,可以设置是否录制非HTML资源,只有选择了“Record within the current script step”时,List of Resource Attributes才会被录制到。非HTML资源的例子是gif和jpg图象文件。
通过修改HTTP头可以传递给服务器一些附加的请求信息。使用HTTP头允许请求中包含其他的内容类型(Content_type),象压缩文件一样。还可以只请求特定状态下的web页面。
所有的Web Vusers ,HTTP模式下的WAP Vusers或者回放模式下的Wireless Session Protocol(WSP),都支持web_url函数。
web_image

语法:
Int web_image (const char *StepName, <List of Attributes>, [EXTRARES, <List of Resource Attributes>,] LAST );
返回值
成功时返回LR_PASS (0),失败时返回 LR_FAIL (1)。
参数:
StepName:VuGen中树形视图中显示的名称,在自动事务处理中也可以用做事务的名称。
List of Attributes(服务器端和客户端映射的图片):SRC属性是一定会被录制到的,其他的ALT、Frame、TargetFrame、Ordinal则是有的话会被录制到。
1、ALT:描述图象的元素。用鼠标指向图象时,所浮出来的文字提示。
2、SRC:描述图象的元素,可以是图象的文件名. 如: button.gif。也可以使用SRC/SFX来指定图象路径的后缀。所有拥有相同此后缀的字符串都会被匹配到。
3、Frame:录制操作时所在的Frame的名称。
4、TargetFrame:见List of Attributes的同名参数。
5、Ordinal:参见Web_link的同名参数。
List of Attributes(客户端映射的图片):
1、AreaAlt:鼠标单击区域的ALT属性。
2、AreaOrdinal:鼠标单击区域的顺序号。
3、MapName:图象的映射名。
List of Attributes(服务器端映射的图片):尽管点击坐标不属于属性,但还是以属性的格式来使用。
1、Xcoord:点击图象时的X坐标。
2、Ycoord:点击图象时的Y坐标。
EXTRARES:分隔符,标记下一个参数是资源属性的列表了。
List of Resource Attributes:参见List of Resource Attributes一节。
LAST:属性列表结束的标记符。
说明
web_image模拟鼠标在指定图片上的单击动作。此函数必须在有前置操作的上下文中使用。
在Toos—Recording Option,如果录制级别设为基于HMTL的录制方式时,web_image才会被录制到。
web_image支持客户端(client-side)和服务器端server-side的图片映射。
在录制选项中,Toos—Recording Option下,Recording选项中,有一个Advanced HTML选项,可以设置是否录制非HTML资源,只有选择了“Record within the current script step”时,List of Resource Attributes才会被录制到。非HTML资源的例子是gif和jpg图象文件。
通过修改HTTP头可以传递给服务器一些请求附加信息。使用HTTP头允许请求中包含内容,如同压缩文件一样。还可以只请求特定状态的web页面。
web_image支持Web虚拟用户,不支持WAP虚拟用户。
例子
下面的例子模拟用户单击Home图标以回到主页(黑体部分):
web_url("my_home", "URL=http://my_home/", LAST);
web_link("Employees", "Text=Employees", LAST);
web_image("Home.gif", "SRC=../gifs/Buttons/Home.gif", LAST);
web_link("Library", "Text=Library", LAST);
web_image("Home.gif", "SRC=../../gifs/buttons/Home.gif", LAST);
下面的例子模拟用户在客户端映射的图片上单击:
web_image("dpt_house.gif",
"Src=../gifs/dpt_house.gif",
"MapName=dpt_house",
"AreaOrdinal=4",
LAST);
下面的例子模拟用户在服务端映射的图片上单击:
web_image("The Web Developer's Virtual Library",
"Alt=The Web Developer's Virtual Library",
"Ordinal=1",
"XCoord=91",
"YCoord=17",
LAST);
下面是一个使用文件名后缀的例子:它指定了dpt_house.gif作为后缀,所以象../gifs/dpt_house.gif、/gifs/dpt_house.gif、gifs/dpt_house.gif、/dpt_house.gif等都会匹配到。
web_image("dpt_house.gif","Src/sfx=dpt_house.gif", LAST);
web_link
语法:
Int web_link (const char *StepName, <List of Attributes>, [EXTRARES, <List of Resource Attributes>,] LAST );
返回值
成功时返回LR_PASS (0),失败时返回 LR_FAIL (1)。
参数:
StepName:VuGen中树形视图中显示的名称,在自动事务设置中也被用做事务名称。
List of Attributes:支持下列的属性:
1. Text:超链接中的文字,必须精确匹配。
2. Frame:录制操作时所在的Frame的名称。
3. TargetFrame、ResourceByteLimit:见List of Attributes一节。
4. Ordinal:如果用给出的属性(Attributes)筛选出的元素不唯一,那么VuGen使用此属性来指定其中的一个。例如:“SRC=abc.gif”,“Ordinal=3”标记的是SRC的值是“abc.gif”的第3张图片。
EXTRARES:表明下面的参数将会是list of resource attributes了。
LAST:结尾标示符。
说明
模拟鼠标在由若干个属性集合描述的链接上进行单击。此函数必须在前置动作的上下文中才可以执行。
web_link 仅仅在基于HTML的录制方式中才会被VuGen捕捉到。
非HTML生成的资源的例子有.gif 和.jpg图像。对于List of Resource Attributes参数来说,仅仅当Recording Options--Recording --HTML-based script-- Record within the current script step选项被选中时,它们才会被插入到代码中。
可以通过改变HTTP头信息给服务器传递一些附加信息。使用HTTP头信息可以,允许响应体中包含其他的内容类型(Content-Type),例如压缩文件,或者只有满足了特定的状态才去请求web页。
此函数值支持Web虚拟用户,不支持WAP虚拟用户。
web_submmit_form

语法:
Int web_submit_form (const char *StepName, <List of Attributes>, <List of Hidden Fields>, ITEMDATA, <List of Data Fields>, [ EXTRARES, <List of Resource Attributes>,] LAST );
返回值
成功时返回LR_PASS (0),失败时返回 LR_FAIL (1)。
参数:
StepName:Form的名字。VuGen中树形视图中显示的名称,在自动事务处理中也可以用做事务的名称。
List of Attributes:支持以下属性:
1. Action:Form中的ACTION属性,指定了完成Form中的操作用到的URL。也可以使用“Action/sfx” 表示使用此后缀的所有Action。
2. Frame:录制操作时所在的Frame的名称。
3. TargetFrame、ResourceByteLimit:见List of Attributes的同名参数。
4. Ordinal:参见Web_link的同名参数。
VuGen通过记录数据域唯一的标识每个Form。如果这样不足以识别Form,VuGen会记录Action 属性。如果还不足以识别,则会记录Ordinal 属性,这种情况下不会记录Action属性。
List of Hidden Fields:补充属性(Serves)。通过此属性可以使用一串隐含域来标识Form。使用下面的格式:
STARTHIDDENS,
"name=n1", "value=v1", ENDITEM,
"name=n2", "value=v2", ENDITEM,
ENDHIDDENS,
List of Data Fields
Data项用来标识form。Form是通过属性和数据来共同识别的。
使用下面的格式来表示数据域列表
"name=n1", "value=v1", ENDITEM,
"name=n2", "value=v2", ENDITEM,
ITEMDATA:Form中数据和属性的分隔符。
EXTRARES:一个分隔符,标记下一个参数是资源属性的列表了。
List of Resource Attributes:参见List of Resource Attributes一节。
LAST:属性列表结束的标记符。
说明
web_submit_form 函数用来提交表单。此函数可能必须在前一个操作的上下文中执行。在Toos—Recording Option,只有录制级别设为基于HMTL的录制方式,web_image才会被录制到。
在录制选项中,Toos—Recording Option下,Recording选项中,有一个Advanced HTML选项,可以设置是否录制非HTML资源,只有选择了“Record within the current script step”时,List of Resource Attributes才会被录制到。非HTML资源的例子是gif和jpg图象文件。
通常情况下,如果录制了web_submit_form 函数,VuGen会把“name”和“value”一起录制到ITEMDATA属性中。如果不想在脚本中以明文显示“value”,可以对它进行加密。把“Value”改为“EncryptedValue”,然后把录制到的值改为加密后的值。
例如:可以把 "Name=grpType", "Value=radRoundtrip", ENDITEM
改为:"Name=grpType", EncryptedValue=409e41ebf102f3036b0549c799be3609", ENDITEM
如果你完整的安装了LoadRunner,那么打开开始菜单--Mercury LoadRunner—Tools--Password Encoder,这个小工具是用来加密字符串的。把需要加密的值粘贴到Password一栏,再点Generate按钮。加密后的字符串会出现在Encoded string框中。接着点Copy按钮,然后把它粘贴到脚本中,覆盖原来显示的“Value”。
加密的另一种方法时使用lr_decrypt函数。方法:选择整个字符串,例如“Value=radRoundtrip”(注意不要选择引号),右击鼠标,选择Encrypt string选现,脚本会变为:
"Name=grpType", lr_decrypt("40d176c46f3cf2f5fbfaa806bd1bcee65f0371858163"), ENDITEM,
web_submit_form支持Web虚拟用户,不支持WAP虚拟用户。
例子:
下面的例子中,web_submit_form 函数的名字是“employee.exe”。此函数提交了一个请求,此请求包含雇员信息John Green。此函数没有使用属性(Attributes)是因为通过数据项已经能唯一的标识这个Form了。
web_submit_form("employee.exe",
ITEMDATA,
"name=persons", "value=John Green - John", ENDITEM,
"name=go_page", "value=Go to Page", ENDITEM,
LAST);
web_submmit_data

语法:
Int web_submit_data ( const char *StepName, <List of Attributes>, ITEMDATA, <List of data>, [ EXTRARES, <List of Resource Attributes>,] LAST );
返回值
返回LR_PASS(0)代表成功,LR_FAIL(1)代表失败。
参数:
StepName:步骤名称,VuGen中树形视图显示的名称。
List of Attributes:支持以下属性:
1. Action:Form中的ACTION属性,指定了完成Form中的操作用到的URL。
2. Method:表单提交方法:POST或GET(默认是POST)。
3. EncType:编码方式。
4. EncodeAtSign:是否使用ASCII值对符号“@”编码。Yes或者 No。
5. TargetFrame:包含当前链接或资源的Frame。参见List of Attributes的同名参数。
6. Referer、Mode:参见List of Attributes的同名参数。
ITEMDATA:数据域和属性的分隔符。
List of Data:
数据域列表定义了表单提交的内容。由于此请求是上下文无关的,因此数据域包含了所有的隐含域。使用Form的编码规则组织数据域。
数据域列表可以使用下面任意一种格式:
"name=n1", "value=v1", ENDITEM,
"name=n2", "EncryptedValue=qwerty", ENDITEM,
EXTRARES:分隔符,标记下一个参数将是资源属性的列表。
List of Resource Attributes:参见List of Resource Attributes。
LAST:结束标记符。
说明
web_submit_data函数处理无状态或者上下文无关的表单提交。它用来生成表单的GET或POST请求,这些请求与Form自动生成的请求是一样的。发送这些请求时不需要表单上下文。
当VuGen设为基于URL的录制模式,或者基于HTML的录制方式但是Recording Options—HTML Advanced 下的A script containing explicit URLs only 选项被选中时,web_submmit_data函数才会录制到。
不论你采用URL查询的方式(GET),还是采用请求体发送(POST)的方式,此函数都指示出Form中的数据是如何发送到服务器的。
如果VuGen处于HTTP录制模式下,此时记录Web进程时,会产生此函数。在提交Form时,如果无法生成web_submit_form函数,VuGen也会生成web_submit_data函数。
在录制选项中,Toos—Recording Option下—Recording选项中,有一个Advanced HTML选项,可以设置是否录制非HTML资源。只有选择了“Record within the current script step”时,List of Resource Attributes才会被录制到。非HTML资源的例子是gif和jpg图象文件。
EncType属性给出一个内容类型,指定其做为“Content-Type”请求头的值。它指示了根据参数生成HTTP请求时使用的编码类型(不是URL-encoding就是multi-part)可以是下面的格式:
1. “EncType=application/x-www-form-urlencoded”
2. “EncType=multipart/form-data” (任何的“; boundary=”都会被默认忽略掉)
3. “EncType=” (空串,表明没有产生内容类型(“Content-Type”)请求头)
任何对于“EncType”的指定都会覆盖web_add_[auto_]header函数指定的Content-Type。当省略了“EncType”时,任何一个web_add_[auto_]header函数都会起作用。如果既没有指定EncType也没有web_add_[auto_]header函数,且“Method=POST”,“application/x-www-form-urlencoded”会做为默认值来使用。其他情况下,不会产生Content-Type请求头。
ContentType:文件类型标识符,如果“EncType”是“multipart/form-data”用来上传文件时,需要用到“ContentType”。当在ITEMDATA中的Data子句中指定了“File=Yes”,且文件也在此子句中,ContentType才适用,此时它会作为同一个子句的值来传递。
正常情况下,“Content-Type”根据所上传文件的扩展名自动生成。例如:
7d025e2b16b064e\r\n Content-Disposition: form-data; name="uploaded_file"; filename="D:\\temp\\a.txt"\r\n Content-Type: text/plain\r\n \r\n
无论如何,对于非浏览器的程序来说是特殊的,根据文件类型生成的“ContentType”不一定是正确的。这时,通过手工指定来覆盖默认的“ContentType”。如果指定了空值,那么“Content-Type”头将不包含在文件中。
如果没有显示的指定“ContentType”的值,当上传的文件为空时,不管文件扩展名是什么,都默认使用“application/x-unknown-content-type”做为”ContentType”的值。
VuGen不会检查指定的ContentType是否有效。
通常情况下,如果录制了web_submit_data 函数,VuGen会把“name”和“value”一起录制到ITEMDATA一节中。如果不想在脚本中以明文显示“value”,可以对它进行加密。把“Value”改为“EncryptedValue”,然后把录制到的值改为加密后的值。请参考web_submit_form中相关的内容。
所有的Web虚拟用户,运行在HTTP模式下的WAP用户,运行在WSP回放模式下的WAP用户都可以使用本函数。
例子
下面的例子中,web_submit_data函数使用POST方法提交了一个表单。
web_submit_data("default.aspx",
"Action=http://lazarus/flightnet/default.aspx",
"Method=POST",
"TargetFrame=",
"RecContentType=text/html",
"Referer=http://lazarus/flightnet/",
"Snapshot=t7.inf",
"Mode=HTML",
ITEMDATA,
"Name=grpType", "Value=radRoundtrip", ENDITEM,
"Name=lstDepartingCity", "Value=DEN", ENDITEM,
"Name=lstDestinationCity", "Value=LAX", ENDITEM,
"Name=txtDepartureDate", "Value=8/19/2003", ENDITEM,
"Name=txtReturnDate", "Value=8/19/2003", ENDITEM,
"Name=txtQuantity", "Value=1", ENDITEM,
"Name=radClass", "Value=1", ENDITEM,
"Name=radSeat", "Value=1", ENDITEM,
"Name=btnAvailableFlights", "Value=Next >", ENDITEM,
LAST);
下面的例子, web_submit_data函数使用POST方法提交了2个文件。
web_submit_data("Attachments",
"Action=http://barton.cottage@.Devonshire.uk/Attachments?YY=45434",
"Method=POST",
"EncType=multipart/form-data",
"TargetFrame=",
"RecContentType=text/html",
"Referer=http:///barton.cottage@.Devonshire.uk/Compose?YY=20435",
"Snapshot=t5.inf",
"Mode=HTML",
ITEMDATA, "Name=userFile0",
"Value=E:\\sense_sensibility\\Elinor.txt",
"File=yes",
"ContentType=text/html", // 覆盖了文本文件默认的“text/plain” 值。
ENDITEM,
"Name=userFile1",
"Value=E:\\sense_sensibility\\Marianne.jpg",
"File=yes",
ENDITEM,
LAST);
web_custom_request

语法:
Int web_custom_request (const char *RequestName, <List of Attributes>,
[EXTRARES, <List of Resource Attributes>,] LAST );
返回值
返回LR_PASS(0)代表成功,LR_FAIL(1)代表失败。
参数:
RequestName:步骤的名称,VuGen中树形视图中显示的名称。
List of Attribute:支持的属性有以下几种:
1. URL:页面地址。
2. Method :页面的提交方式,POST或GET。
3. TargetFrame:包含当前链接或资源的frame的名称。参见List of Attributes的同名参数。
4. EncType:编码类型。
5. RecContentType:响应头的内容类型。参见List of Attributes的同名参数。
6. Referer:参见List of Attributes的同名参数。
7. Body:请求体。参见List of Attributes的同名参数。
8. RAW BODY:参见List of Attributes的同名参数。
9. BodyFilePath:作为请求体传送的文件的路径。它不能与下面的属性一起使用:Body,或者其他Body属性或Raw Body属性包括BodyBinary,BodyUnicode, RAW_BODY_START或Binary=1。
10. Resource、ResourceByteLimit、Snapshot、Mode:参见List of Attributes的同名参数。
11. ExtraResBaseDir:参见List of Attributes的同名参数。
12. UserAgent:用户代理,它是一个HTTP头的名字,用来标识应用程序,通常是浏览器,它呈现的是用户和服务器的交互。
例如:头信息“User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)”识别的是Window NT下的IE浏览器6.0。其他的User-Agent的值用来描述其他的浏览器,或者非浏览器程序。通常,一个应用程序中所有的请求都使用相同的用户代理,录制者作为一个运行时参数来指定(Run-Time Setting—Browser Emulation—User Agent)。不管怎么说,即使是在一个简单的浏览器进程中,仍有可能会用到直接与服务器交互的非浏览器组件(例如ActiveX控件),通常他们有着不同于浏览器的用户代理属性。指定“UserAgent”表示这是一个非浏览器的请求。指定的字符串被HTTP头“User-Agent:” 使用,在某些情况下,它同时会影响回放脚本时的行为。例如,不使用浏览器缓存,假设指定的URL属于资源等等。
LoadRunner本身不检查指定的字符串与浏览器本身的值是否相同。
13. Binary:“Binary=1”表示页面请求体中的每一个以\\x##形式出现的值(在这里“##”代表2个十六进制数字),都会被替换为单字节的十六进制的值。
如果“Binary=0”(默认值),所有的字符序列只是按照字面的值传递。
需要注意双斜杠的用法。在C编译器中双斜杠被解释为单斜杠。如果不需要零字节,单斜杠可以在Binary不等于1的情况下使用(例如,使用\x20代替\\x20)。如果需要零字节,那么只能使用\\x00且设置 “Binary=1”,\x00在逻辑上会被截断。

Loadrunner函数中文解释

2009年09月26日 星期六上午 09:49

web_url

语法:
Int Web_url(const char *name, const char * url, <Lists of Attributes>, [EXTRARES,<Lists of Resource Attributes>,LAST)

返回值
成功时返回LR_PASS (0),失败时返回 LR_FAIL (1)。

参数:
Name:VuGen中树形视图中显示的名称,在自动事务处理中也可以用做事务的名称。

url:页面url地址。

List of Attributes

EXTRARES:分隔符,标记下一个参数是资源属性的列表了。

List of Resource Attributes

LAST:属性列表结束的标记符。

说明

Web_url根据函数中的URL属性加载对应的URL,不需要上下文。

只有VuGen处于URL-based或者HTML-based(此时A scrīpt containing explicit URLs only选项被选中时)的录制模式时,web_url才会被录制到。

可以使用web_url 模拟从FTP服务器上下载文件。web_url 函数会使FTP服务器执行文件被真实下载时的操作。除非手工指定了"FtpAscii=1",下载会以二进制模式完成。

在录制选项中,Toos—Recording Option下,Recording选项中,有一个Advanced HTML选项,可以设置是否录制非HTML资源,只有选择了“Record within the current scrīpt step”时,List of Resource Attributes才会被录制到。非HTML资源的例子是gif和jpg图象文件。

通过修改HTTP头可以传递给服务器一些附加的请求信息。使用HTTP头允许请求中包含其他的内容类型(Content_type),象压缩文件一样。还可以只请求特定状态下的web页面。

所有的Web Vusers ,HTTP模式下的WAP Vusers或者回放模式下的Wireless Session Protocol(WSP),都支持web_url函数。

web_image

语法:
Int web_image (const char *StepName, <List of Attributes>, [EXTRARES, <List of Resource Attributes>,] LAST );

返回值
成功时返回LR_PASS (0),失败时返回 LR_FAIL (1)。

参数:
StepName:VuGen中树形视图中显示的名称,在自动事务处理中也可以用做事务的名称。

List of Attributes(服务器端和客户端映射的图片):SRC属性是一定会被录制到的,其他的ALT、Frame、TargetFrame、Ordinal则是有的话会被录制到。

1、ALT:描述图象的元素。用鼠标指向图象时,所浮出来的文字提示。

2、SRC:描述图象的元素,可以是图象的文件名. 如: button.gif。也可以使用SRC/SFX来指定图象路径的后缀。所有拥有相同此后缀的字符串都会被匹配到。

3、Frame:录制操作时所在的Frame的名称。

4、TargetFrame:见List of Attributes的同名参数。

5、Ordinal:参见Web_link的同名参数。

List of Attributes(客户端映射的图片):

1、AreaAlt:鼠标单击区域的ALT属性。

2、AreaOrdinal:鼠标单击区域的顺序号。

3、MapName:图象的映射名。

List of Attributes(服务器端映射的图片):尽管点击坐标不属于属性,但还是以属性的格式来使用。
1、Xcoord:点击图象时的X坐标。

2、Ycoord:点击图象时的Y坐标。

EXTRARES:分隔符,标记下一个参数是资源属性的列表了。

List of Resource Attributes:参见List of Resource Attributes一节。

LAST:属性列表结束的标记符。

说明

web_image模拟鼠标在指定图片上的单击动作。此函数必须在有前置操作的上下文中使用。

在Toos—Recording Option,如果录制级别设为基于HMTL的录制方式时,web_image才会被录制到。
web_image支持客户端(client-side)和服务器端server-side的图片映射。

在录制选项中,Toos—Recording Option下,Recording选项中,有一个Advanced HTML选项,可以设置是否录制非HTML资源,只有选择了“Record within the current scrīpt step”时,List of Resource Attributes才会被录制到。非HTML资源的例子是gif和jpg图象文件。

通过修改HTTP头可以传递给服务器一些请求附加信息。使用HTTP头允许请求中包含内容,如同压缩文件一样。还可以只请求特定状态的web页面。

web_image支持Web虚拟用户,不支持WAP虚拟用户。

例子

下面的例子模拟用户单击Home图标以回到主页(黑体部分):

web_url("my_home", "URL=http://my_home/", LAST);

web_link("Employees", "Text=Employees", LAST);

web_image("Home.gif", "SRC=../gifs/Buttons/Home.gif", LAST);

web_link("Library", "Text=Library", LAST);

web_image("Home.gif", "SRC=../../gifs/buttons/Home.gif", LAST);

下面的例子模拟用户在客户端映射的图片上单击:

web_image("dpt_house.gif",

"Src=../gifs/dpt_house.gif",

"MapName=dpt_house",

"AreaOrdinal=4",

LAST);

下面的例子模拟用户在服务端映射的图片上单击:

web_image("The Web Developer's Virtual Library",

"Alt=The Web Developer's Virtual Library",

"Ordinal=1",

"XCoord=91",

"YCoord=17",

LAST);

下面是一个使用文件名后缀的例子:它指定了dpt_house.gif作为后缀,所以象../gifs/dpt_house.gif、/gifs/dpt_house.gif、gifs/dpt_house.gif、/dpt_house.gif等都会匹配到。

web_image("dpt_house.gif",

"Src/sfx=dpt_house.gif", LAST);

web_link

语法:
Int web_link (const char *StepName, <List of Attributes>, [EXTRARES, <List of Resource Attributes>,] LAST );

返回值
成功时返回LR_PASS (0),失败时返回 LR_FAIL (1)。

参数:
StepName:VuGen中树形视图中显示的名称,在自动事务设置中也被用做事务名称。

List of Attributes:支持下列的属性:

1.Text:超链接中的文字,必须精确匹配。

2.Frame:录制操作时所在的Frame的名称。

3.TargetFrame、ResourceByteLimit:见List of Attributes一节。

4.Ordinal:如果用给出的属性(Attributes)筛选出的元素不唯一,那么VuGen使用此属性来指定其中的一个。例如:“SRC=abc.gif”,“Ordinal=3”标记的是SRC的值是“abc.gif”的第3张图片。

EXTRARES:表明下面的参数将会是list of resource attributes了。

LAST:结尾标示符。

说明

模拟鼠标在由若干个属性集合描述的链接上进行单击。此函数必须在前置动作的上下文中才可以执行。

web_link 仅仅在基于HTML的录制方式中才会被VuGen捕捉到。

非HTML生成的资源的例子有.gif 和.jpg图像。对于List of Resource Attributes参数来说,仅仅当Recording Options--Recording --HTML-based scrīpt-- Record within the current scrīpt step选项被选中时,它们才会被插入到代码中。

可以通过改变HTTP头信息给服务器传递一些附加信息。使用HTTP头信息可以,允许响应体中包含其他的内容类型(Content-Type),例如压缩文件,或者只有满足了特定的状态才去请求web页。

此函数值支持Web虚拟用户,不支持WAP虚拟用户。

web_submmit_form

语法:
Int web_submit_form (const char *StepName, <List of Attributes>, <List of Hidden Fields>, ITEMDATA, <List of Data Fields>, [ EXTRARES, <List of Resource Attributes>,] LAST );

返回值
成功时返回LR_PASS (0),失败时返回 LR_FAIL (1)。

参数:
StepName:Form的名字。VuGen中树形视图中显示的名称,在自动事务处理中也可以用做事务的名称。
List of Attributes:支持以下属性:

1.Action:Form中的ACTION属性,指定了完成Form中的操作用到的URL。也可以使用“Action/sfx” 表示使用此后缀的所有Action。

2.Frame:录制操作时所在的Frame的名称。

3.TargetFrame、ResourceByteLimit:见List of Attributes的同名参数。

4.Ordinal:参见Web_link的同名参数。

VuGen通过记录数据域唯一的标识每个Form。如果这样不足以识别Form,VuGen会记录Action 属性。如果还不足以识别,则会记录Ordinal 属性,这种情况下不会记录Action属性。

List of Hidden Fields:补充属性(Serves)。通过此属性可以使用一串隐含域来标识Form。使用下面的格式:

STARTHIDDENS,

"name=n1", "value=v1", ENDITEM,

"name=n2", "value=v2", ENDITEM,

ENDHIDDENS,

List of Data Fields

Data项用来标识form。Form是通过属性和数据来共同识别的。

使用下面的格式来表示数据域列表

"name=n1", "value=v1", ENDITEM,

"name=n2", "value=v2", ENDITEM,

ITEMDATA:Form中数据和属性的分隔符。

EXTRARES:一个分隔符,标记下一个参数是资源属性的列表了。

List of Resource Attributes:参见List of Resource Attributes一节。

LAST:属性列表结束的标记符。

说明

web_submit_form 函数用来提交表单。此函数可能必须在前一个操作的上下文中执行。在Toos—Recording Option,只有录制级别设为基于HMTL的录制方式,web_image才会被录制到。

在录制选项中,Toos—Recording Option下,Recording选项中,有一个Advanced HTML选项,可以设置是否录制非HTML资源,只有选择了“Record within the current scrīpt step”时,List of Resource Attributes才会被录制到。非HTML资源的例子是gif和jpg图象文件。

通常情况下,如果录制了web_submit_form 函数,VuGen会把“name”和“value”一起录制到ITEMDATA属性中。如果不想在脚本中以明文显示“value”,可以对它进行加密。把“Value”改为“EncryptedValue”,然后把录制到的值改为加密后的值。

例如:可以把 "Name=grpType", "Value=radRoundtrip", ENDITEM

改为:"Name=grpType", EncryptedValue=409e41ebf102f3036b0549c799be3609", ENDITEM

如果你完整的安装了LoadRunner,那么打开开始菜单--Mercury LoadRunner—Tools--Password Encoder,这个小工具是用来加密字符串的。把需要加密的值粘贴到Password一栏,再点Generate按钮。加密后的字符串会出现在Encoded string框中。接着点Copy按钮,然后把它粘贴到脚本中,覆盖原来显示的“Value”。

加密的另一种方法时使用lr_decrypt函数。方法:选择整个字符串,例如“Value=radRoundtrip”(注意不要选择引号),右击鼠标,选择Encrypt string选现,脚本会变为:

"Name=grpType", lr_decrypt("40d176c46f3cf2f5fbfaa806bd1bcee65f0371858163"), ENDITEM,

web_submit_form支持Web虚拟用户,不支持WAP虚拟用户。

例子:

下面的例子中,web_submit_form 函数的名字是“employee.exe”。此函数提交了一个请求,此请求包含雇员信息John Green。此函数没有使用属性(Attributes)是因为通过数据项已经能唯一的标识这个Form了。

LoadRunner参数化

2009年09月25日 星期五下午 02:22

一、关于参数的定义
函数中参数的值就是在录制过程中输入的实际值。
例如,你录制了一个 Web 应用程序的脚本。脚本生成器生成了一个声明,该声明搜索名称为 “软件测试” 的图书的数据库。当你用多个虚

拟用户和迭代回放脚本时,也许你不想重复使用相同的值“ 软件测试”,还需要其他的值如“项目管理” 。例如平常经常用到的,登陆界

面输入用户名和密码,那么,你就可以用参数来取代这个常量。结果就是你可以用指定的数据源的数值来取代参数值。数据源可以是一个文

件,也可以是内部产生的变量。
用参数表示用户的脚本有两个优点:① 可以使脚本的长度变短。② 可以使用不同的数值来测试你的脚本。例如,如果你企图搜索不同名称

的图书,你仅仅需要写提交函数一次。在回放的过程中,你可以使用不同的参数值,而不只搜索一个特定名称的值。
参数化包含以下两项任务:① 在脚本中用参数取代常量值。② 设置参数的属性以及数据源。
参数化仅可以用于一个函数中的参量。你不能用参数表示非函数参数的字符串。另外,不是所有的函数都可以参数化的
二、参数的创建
可以指定名称和类型来创建参数。不存在对脚本中参数个数的限制。在 Web 程序的用户脚本中,你可以使用如下过程在基于文本的脚本视图

中创建参数。或者,也可以在基于图标的树形视图中创建参数。
在基于文本的脚本视图中创建一个参数:
1 、 将光标定位在要参数化的字符上,点击右键。打开弹出菜单。
2 、 在弹出菜单中,选择 “Replace with a Parameter” 。选择或者创建参数的对话框弹出。
3 、 在 “Parameter name” 中输入参数的名称,或者选择一个在参数列表中已经存在的参数。
4 、 在 “Parameter type” 下拉列表中选择参数类型
1)、 Date/Time Date/Time 用当前的日期 / 时间替换参数。要指定一个 Date/Time 格式,你可以从菜单列表中选择格式,或者指定

你自己的格式。这个格式应该和你脚本中录制的 Date/Time 格式保持一致。你可以设置一个时间参数的偏移量,如果你打算测试下个月的日

期,你就可以选择偏移量为30。你也可以设置前偏移量和后偏移量,默认的是前偏移量。另外你可以命令vguen在工作日使用date值,不包括

周六和周日(没有明白这个的具体用处,明白的请告知)。

2 )、 Group Name Group Name 用虚拟用户组名称替换参数。在创建 scenario 的时候,你可以指定虚拟用户组的名称。当从用户脚

本生成器运行脚本的时候,虚拟用户组名称总是 None 。
char *c =" {NewParam}"; //%05s
char *d="{NewParam_1}";//%07s
lr_log_message("group(5s) is %s,group(7s)is %s",lr_eval_string (c),lr_eval_string (d));
显示的结果为:group(5s)is 0None,group(7s)is 000None
3). Iteration Number Iteration Number 用当前的迭代数目替换参数
设置迭代次数为3
char *c =" {NewParam}"; //%05s
char *d="{NewParam_1}";//%07s
lr_log_message("Iteration(5s) is %s,Iteration(7s)is %s",lr_eval_string (c),lr_eval_string (d));
结果为:Iteration(5s) is 00001,Iteration(7s)is 0000001
Iteration(5s) is 00002,Iteration(7s)is 0000002
Iteration(5s) is 00003,Iteration(7s)is 0000003
4)、 Load Generator Name Load Generator Name 用脚本负载生成器的名称替换参数。负载生成器是虚拟用户在运行的计算机。
5) 、 Random Number Random Number 用一个随机数替换参数。通过指定最大值和最小值来设置随机数的范围。
6)、 Unique Number Unique Number 用一个唯一的数字来替换参数。你可以指定一个起始数字和一个块的大小。
7 、 Vuser ID Vuser ID 用分配给虚拟用户的 ID 替换参数, ID 是由 Loadrunner 的控制器在 scenario 运行时生成的。如果你从

脚本生成器运行脚本的话,虚拟用户的 ID 总是 -1
8、User-Defined Functions ―― 调用外部 DLL 函数生成的数据 ,函数必须是如下格式:
__declspec(dllexport) char *<functionName>(char *, char *) 例如:__declspec(dllexport) char *UF_GetVersion(char *x1, char

*x2) {return "Ver2.0";}

9、table或file 从已存在的数据库中导入文件
可以使用下列两种方式之一:
1. 使用 Microsoft Query (要求在系统上先安装 MS Query )。
2. 指定数据库连接字符串和 SQL 语句。
用户脚本生成器在从数据库中导入数据的过程中提供了一个向导。在向导中,你指明如何导入数据-通过 MS Query 创建查询语句或者直接

书写 SQL 语句。在导入数据以后,以 .dat 为后缀并作为正规的参数文件保存。
要开始导入数据库中数据的过程,在参数属性对话框中点击“ Data Wizard ”,则,数据库查询向导弹出。
要创建新的查询
1. 选择“ Create new query ”。如果需要 MS Query 的帮助,选择“ Show me how to use Microsoft Query ”,然后点击“ Finish ”


如果你还没有安装 Microsoft Query , Loadrunner 会提示你这个功能不可用。在进行之前,从 Microsoft Office 中安装 MS Query 。
2. 在 Microsoft Query 中遵循以下步骤,导入期望的表和列。
3. 在完成数据的导入后,选择“ Exit and return to Virtual User Generator ”,然后点击“ Finish ”。在参数属性对话框中数据库

记录以 data 文件的形式显示出来。
要在 MS Query 中编辑并查看数据,选择“ View data or edit in Microsoft Query ”。若要结束,则选择“ File>Exit and return to

Virtual User Generator ”返回到脚本生成器。
4. 在“ Select Column ”部分,指定包含当前参数数据的列可以指定列号或者列名。注意:列标题默认为第 0 行( row 0 )。
5. 从“ Select next row ”列表中选择一个更新方法来告诉虚拟用户在脚本指定的过程中如何选择表中的数据。可选项是: Sequential

、 Random 、 Unique 或者 Same Line As 。
6. 如果选择“ Advance row each iteration ”,虚拟用户在每次迭代的时候会使用新的一行的数据而不是重复同样的数据。
要指定数据库连接或者 SQL 语句
1. 选择“ Specify SQL Statement ”,然后点击“ Next ”。
2. 点击“ Create ”指定一个新的连接字符串。选择数据源的窗口弹出。
3. 选择已有的数据源,或者点击“ New ”创建一个新的数据源。向导将提示你穿过创建 ODBC 数据源的过程。在完成后,连接字符串就会

在连接字符串框中显示出来。
4. 在 SQL 框中,输入或者粘贴 SQL 语句。
5. 点击“ Finish ”继续 SQL 语句并导入数据。数据库记录将以 data 文件的形式显示在参数属性框中。
6. 在“ Select Column ”部分中,指定包含当前参数数据的列。你可以指定列号或者列名。
7. 从“ Select next row ”列表中选择一个更新方法来告诉虚拟用户在脚本指定的过程中如何选择表中的数据。可选项是: Sequential

、 Random 、 Unique 或者 Same Line As 。
8. 如果选择“ Advance row each iteration ”,虚拟用户在每次迭代的时候会使用新的一行的数据而不是重复同样的数据。
数据文件 数据文件包含着脚本执行过程中虚拟用户访问的数据。局部和全局文件中都可以存储数据。可以指定现有的 ASCII 文件、用

脚本生成器创建一个新的文件或者引入一个数据库。在参数有很多已知值的时候数据文件非常有用。数据文件中的数据是以表的形式存储的

。一个文件中可以包含很多参数值。每一列包含一个参数的数据。列之间用分隔符隔开,比如说,用逗号。 对数据文件设置参数属性

如果使用文件作为参数的数据源,必须指定以下内容:文件的名称和位置、包含数据的列、文件格式,包括列的分隔符、更新方法。

如果参数的类型是“ File” ,打开参数属性( Parameter Properties )对话框,设置文件属性如下:
1 、 在 “File path” 中输入文件的位置,或者点击 “Browse” 指定一个已有文件的位置。缺省情况下,所有新的数据文件名都是

“parameter_name.dat” ,注意,已有的数据文件的后缀必须是 .dat 。
2 、 点击 “Edit” 。记事本打开,里面第一行是参数的名称,第二行是参数的初始值。使用诸如逗号之类的分隔符将列隔开。对于每一新

的表行开始一行新的数据。 注意:在没有启动记事本的情况下如果想添加列,就在参数属性对话框中点击“ Add Col” ,那么 “Add

new column” 对话框就会弹出。输入新列的名称,点击 “OK” 。脚本生成器就会添加该列到表中,并显示该列的初始值。
3 、 在 “Select Column” 部分,指明包含当前参数数据的列。你可以指定列名或者列号。列号是包含你所需要数据的列的索引。列名显

示在每列的第一行( row 0 )。
4 、 在 “Column delimiter” 中输入列分隔符,你可以指定逗号、空格符等等。
5 、 在 “First data line” 中,在脚本执行的时候选择第一行数据使用。列标题是第 0 行。若从列标题后面的第一行开始的话,那就在

“First data line” 中输入 1 。如果没有列标题,就输入 0 。
6 、 在 “Select next row” 中输入更新方法,以说明虚拟用户在脚本执行的过程中如何选择表中的数据。方法可以是:连续的、随机的

、唯一的、或者与其它参数表的相同行。
6.1 、 顺序( Sequential ):该方法顺序地给虚拟用户分配参数值。如果正在运行的虚拟用户访问数据表的时候,它会取到下一行中可用

的数据。
6.2 、 随机( Random ):该方法在每次迭代的时候会从数据表中取随机数
6.3 、 使用种子取随机顺序( Use Random Sequence with Seed ):如果从 Loadrunner 的控制器来运行 scenario ,你可以指定一个种

子数值用于随机顺序。每一个种子数值在测试执行的时候代表了一个随机数的顺序。无论你何时使用这个种子数值,在 scenario 中同样的

数据顺序就被分配给虚拟用户。如果在测试执行的时候发现了一个问题并且企图使用同样的随机数序列来重复测试,那么,你就可以启动这

个功能(可选项)。
6.4 、 唯一( Unique ): Unique 方法分配一个唯一的有顺序的值给每个虚拟用户的参数。
6.5 、与以前定义的参数取同一行( Same Line As ):该方法从和以前定义过的参数中的同样的一行分配数据。你必须指定包含有该数据

的列。在下拉列表中会出现定义过的所有参数列表。注意:至少其中的一个参数必须是 Sequential 、 Random 或者 Unique 。
如果数据表中有三列,三个参数定义在列表中: id1 , name1 和 title1 ,如下:。
ID Name Title
132 Kim Manager
187 Cassie Engineer
189 Jane VP
对于参数 id1 ,你可以指示虚拟用户使用 Random 方法,而为参数 name1 和 title1 就可以指定方法 “Same Line as id1” 。所以,一

旦 ID“132” 被使用,那么,姓名( Name ) “Kim” 和职位( Title ) “Manager” 同时被使用。
7 、 Updta value on 数据的更新方法
7.1 、 Each iteration ――每次反复都要取新值。
7.2 、 Each occurrence ――只要发现该参数就要重新取值。
7.3 、 Once ――在所有的反复中都使用同一个值
8 、 When out of values 超出范围:(选择数据为 unique 时才可用到)
8.1 、 Abort Vuser ――中止
8.2 、 Continue in a cyclic manner ――继续循环取值
8.3 、 Continue with last value ――取最后一个值
9 、 Allocate Vuser values in the Controller 在控制器中分配值:(选择数据为 unique 时才可用到)

查看文章

   

web_find()和web_reg_find()

2009年09月26日 星期六上午 09:51

这两个函数均用于内容的查找,但两者也有本质的区别,具体介绍如下:
一、web_find()函数
该函数的作用是“在页面中查找相应的内容”,常用参数及含义如下:
web_find("web_find", //定义该查找函数的名称
%vR`}1}0 "RightOf=a", //定义查找字符的右边界
"LeftOf=b", //定义查找字符的左边界
"What=name", //定义查找内容
LAST);
使用该函数注意以下事项:
1、 位置
该函数在页面内容显示出来以后,在页面中进行查找,所以只能写在要查找内容之后
2、 录制模式
该函数只能在基于HTML模式录制的脚本中进行查找
3、 必须启用内容检查选项
在runtime setting->Preferences里面,把Enable image and text check选中,否则不执行该查找函数
4、 在VB和JAVA语法中不支持该函数
该函数有以下一个缺点:
1、 执行效率较低
2、 不返回查找结果情况,如想在执行该函数后根据查找结果做进一步操作时,没有返回值可以依据
例如:
在页面中查找“登录成功”的字符串,如果找到该字符串在日志中输出“登录成功”,如果找不到该字符串,则在日志中输出“登录失败”,此时使用该函数没有依据来做此判断,但使用web_reg_find()函数,使用它其中的SaveCount可以进行判断,具体方法我们下面介绍。
转载请注明出处:http://www.51testing.com/?41972
二、web_reg_find()函数
该函数的作用是“在缓存中查找相应的内容”,常用参数及含义如下:
web_reg_find("Search=Body", //定义查找范围
"SaveCount=ddd", //定义查找计数变量名称
"Text=aaaa", //定义查找内容
LAST);
使用该函数注意以下事项:
1、 位置
该函数写在要查找内容的请求之前,通常情况下写在如下六个函数之前:
Web_castom_request();web_image();web_link();web_submit_data();web_submit_form();web_url()
2、 使用技巧
在该函数的参数中有个“SaveCount”,该参数可以记录在缓存中查找内容出现的次数,我们可以使用该值,来判断要查找的内容是否被找到,下面举个例子来说明:(引用LR的帮助中的例子)
// Run the Web Tours sample
web_url("MercuryWebTours",
"URL=http://localhost/MercuryWebTours/",
"Resource=0",
"RecContentType=text/html",
"Referer=",
"Snapshot=t1.inf",
"Mode=HTML",
LAST);
// Set up check for successful login by looking for "Welcome"
web_reg_find("Text=Welcome",
"SaveCount=Welcome_Count",
LAST);
// Now log in
web_submit_form("login.pl",
"Snapshot=t2.inf",
ITEMDATA,
"Name=username", "Value=jojo", ENDITEM,
"Name=password", "Value=bean", ENDITEM,
"Name=login.x", "Value=35", ENDITEM,
"Name=login.y", "Value=14", ENDITEM,
LAST);
// Check result
if (atoi(lr__string("{Welcome_Count}")) > 0){ //判断如果Welcome字符串出现次数大于0
lr_output_message("Log on successful."); }//在日志中输出Log on successful
else{ //如果出现次数小于等于
lr_error_message("Log on failed"); //在日志中输出Log on failed
return(0); }
我觉得这个方法非常有用,我们可以举一反三,应用到我们实际的项目中
转载请注明出处:http://www.51testing.com/?41972
三、插入函数的方法
1、 手工写入,在需要插入函数的位置手工写入该函数
2、 光标停留在要插入函数的位置,在INSERT菜单中,选择new step,在列表中选择或查找要插入的函数,根据提示填写必要的参数
3、 在tree view模式下,在树状菜单中选中要插入函数的位置,右键,选择insert after或insert before,根据提示填写必要的参数
四、总结
1、 这两个函数函数类型不同,WEB_FIND是普通函数,WEB_REG_FIND是注册函数
2、 WEB_FIND使用时必须开启内容检查选项,而WEB_REG_FIND则不没有此限制
3、 WEB_FIND只能只用在基于HTML模式录制的脚本中,而WEB_REG_FIND没有此限制
4、 WEB_FIND是在返回的页面中进行内容查找,WEB_REG_FIND是在缓存中进行查找
5、 WEB_FIND在执行效率上不如WEB_REG_FIND

LoadRunner脚本编写-- 检查点,关联等函数

2009年09月26日 星期六上午 09:51

1. 错误预防和恢复

参数默认是用{}括起来的,但也可以指定用<>51Testing软件测试网

NTLM或用户登录验证

web_set_user("X\\Y", "Z", "A.com:80");

在域与X上的用户名为Y的用户,使用密码Z来登录到A.com:80。在windows基本验证的时候这个脚本被默认录制下来,但如果web服务器需要更安全的NTLM或更深层次的验证,需要手动的添加这个函数到脚本中。对于NTML验证,用户名必须在域名之后,并且以\分割。使用\等符号,需要使用\\,前面的\用来做转义用,否则会出现警告提示。

zibeike注:在论坛中也看到了一些朋友讨论windows弹出登录框的操作LR无法录制到,导致回放出错,一般出错信息多为“Error -26547: Authentication required, please use web_set_user, e.g. web_set_user("domain\\user", "password", "host:port"); [MsgId: MERR-26547]”,其实这种情况错误信息已经很明显的给你提示了,需要往脚本中添加web_set_user函数即可。

2. IP欺骗(略)

3. 验证检查点

通常脚本录制完后需要手动添加些脚本来来确保预期的操作确实进行了正确的响应(如在操作之后后验证显示的一段文本或者图片)。这些检查可以使用正则表达式。

Web虚拟用户脚本中不会录制到检查点,需要手动添加或者使用VuGen的用户接口来添加函数代码。

最常用的检查点函数是web_reg_find。这个注册函数会查找脚本中下一个操作如web_url后产生的一段文本。它是从返回的缓冲区扫描而不是在接收的页面中查找。这是比web_find更高效的一个函数。

可以使用下面的代码来验证文本出现的次数:

  • web_reg_find("Text=ABC", "SaveCount=abc_count", LAST);
  • web_url("Step", "URL=...", LAST);
    if (strcmp(lr__string("{abc_count}"), "0") == 0)

lr_output_message("not found");

else

lr_output_message("{abc_count} found");

如果想保存并且显示找到的文本,可以使用web_reg_save_param界定左右边界把找到的信息保存到参数中。如下:

  • char *str1,*str2;
  • str1="desired text";
    web_reg_save_param("param","LB/ic=xxx","RB=xxx");
    web_url("some url","URL=www.xxx.com",LAST);
  • str2=lr__string("{param}");
  • if(strcmp(str1,str2)==0) {

lr_output_message("param found");

}else{

lr_output_message("Value found is %s",str2);

}

zibeike注:1)这里想跟大家说下注册函数,在web/http协议的脚本中,注册函数均以web_reg为前缀,这种注册型的函数都是从缓冲区扫描或者获得数据,因此需要提前声明即需要在能获得该查找信息的函数之前添加这些注册函数。例如,web_url()请求了一个页面,我需要验证该页面中是否有某个特定的文本,那需要在web_url()函数之前加上web_reg_find,类似的还有关联的函数web_reg_save_para是一样的,需要放到能获得想要的数据的请求的函数之前。但如果想查看这些函数最终保存的结果,如想打印关联函数web_reg_save_para中保存的参数内容,打印的操作就需要放到请求的函数之后了。

2)web_find和web_reg_find的区别:前面的是查找页面显示的数据,因此需要放在请求页面的函数之后,而且查找的信息是显示的web页面上的信息。后者是注册型函数,需要放到请求的页面之前,而且查找的内容是服务器返回的缓冲数据中查找,所以查找内容应该看html源代码的内容。

基于HTML录制方式的代码,可以使用web_image_check对HTML页面中包含的图片进行验证。并且需要注意的是只有在Runtime Settings > Internet Protocol Preferences选择了"Enable Image and text check"检查点才有效。

LoadRunner脚本实例来验证参数化的取值

2009年09月26日 星期六上午 09:54

问题提出: 主要想试验下,在Controller中,多个用户,多次迭代中参数的取值.

方法:

脚本: 我把取到的参数值和对应的VuserID记录下来保存到一个文件中,下面是例子的脚本

long fileopen;

char *filename = "C:\\temp\\params.log";

vuser_init()

{

if ((fileopen = fopen(filename,"a+")) == NULL)

{

lr_error_message ("file isn't open,path=%s",filename);

return 0;
}
return 0;
}

Action()

{
int id,scid;

char *vuser_group;

//typedef long time_t;

//time_t t;

long t;

char *a = "{aaa}";

char *b = "{bbb}";

lr_whoami(&id, &vuser_group, &scid);

fprintf(fileopen,"%d,%s,%s,%s",id,lr__string (a),lr__string (b),ctime(&t));

return 0;
}

vuser_end()
{
fclose(fileopen);

return 0;

}

参数设置为:

取唯一值,每次迭代更新。

运行时设置的迭代次数为2。

场景的设置:

虚拟用户数:5个

运行模式:没有设置duration,选择的“Run until complete”

完成后的日志文件params.log的内容如下:

1,a1,b1,Thu Jan 01 08:00:05 1970
1,a2,b2,Thu Jan 01 08:00:05 1970
10,a5,b5,Thu Jan 01 08:00:05 1970
10,a6,b6,Thu Jan 01 08:00:05 1970
2,a3,b3,Thu Jan 01 08:00:05 1970
2,a4,b4,Thu Jan 01 08:00:05 1970
30,a9,b9,Thu Jan 01 08:00:05 1970
30,a10,b10,Thu Jan 01 08:00:05 1970
21,a7,b7,Thu Jan 01 08:00:05 1970
21,a8,b8,Thu Jan 01 08:00:05 1970

从生成的日志文件中可以看到VuserID分别为1,2,10,21,30

第一次迭代取参数分别为1,3,5,7,9

第二次迭代取参数分别为2,4,6,8,10

那试验的结果就是每个Vuser取参数的时候相同的Vuser在多个迭代中取的是连续的。不同的Vuser第一个的取值是计算了迭代次数后的那个顺序上的值。

使用Sql生成测试数据

2009年09月26日 星期六上午 10:02

无论您是在用原型证明某一概念,还是开发一个全新的应用程序,或者只是学习 SQL,您都需要在您的应用程序上运行测试数据。为了有效地测试应用程序的性能,您必须拥有足够的测试数据,以便暴露潜在的性能问题。只要可以得到,用实际数据来进行测试总是更可取一些。如果没有可用的实际数据,那么在许多情况下,也可以生成足够的假想数据。一般来说,从头开始构造大量数据是件很容易的工作,您自己就可以快速地独立完成。

本文提供了一些如何利用 SQL 脚本来生成测试数据的示例,而这些脚本本身就是较好的 SQL 实践。并且还讨论了一些为了生成尽可能真实的数据而应该注意的问题。

生成大量记录

即使数据库是新创建且仍然为空的,也总是会带有系统表和视图,因此,您可以按以下方法使用它们:

CREATE TABLE DB2ADMIN.SALES
(CUSTOMER_ID INT NOT NULL, ITEM_ID INT NOT NULL,
SALE_QUANTITY SMALLINT NOT NULL, SALE_DATE DATE NOT NULL);
INSERT INTO SALES
SELECT
SYSFUN.RAND()*500 + 1 AS CUSTOMER_ID,
SYSFUN.RAND()*100 + 1 AS ITEM_ID,
1 + SYSFUN.RAND()*10 AS SALE_QUANTITY,
DATE('01/01/2003') + (SYSFUN.RAND()*200) DAYS AS SALE_DATE
FROM SYSCAT.COLUMNS;

SALES 表中的记录数就与 SYSCAT.COLUMNS 中的完全一样了。请注意,多个列都是用随机值来填充的。例如,SALE_QUANTITY 列中的所有值都是处于 1 到 10 之间,约 10% 的记录具有各不相同的值。如果您需要更多记录,就可以根据需要多次重复执行这条 INSERT 语句。您还可以像下面这样使用交叉连接(CROSS JOIN),以便每条语句获得更多记录:

注意:本例中,表 T1 和 T2 的连接是不含任何条件的,因此,T1 中的每一行会匹配 T2 中的每一行。这种类型的连接称作交叉连接。关于交叉连接的更多信息,请查阅 Joe Celko 的 SQL for Smarties 一书。

注意:这条 INSERT 语句所涉及的事务可能会相当大,以致于您的服务器无法加以处理。如果您遇到“log full”的情况(SQL0964C 数据库的事务日志已满),您可能需要增加日志空间,或者通过指定 T1 或 T2 或两者中的 WHERE 子句来获得一个较小的事务。

您可以使用该方法来生成大量记录,然而,该方法有点过分简单了,因为所有的值都是均匀分布的,而且它们之间不存在相关性。

填充子表

您的数据库中很可能存在多对一的关系。下列示例展示了如何填充子表,以使每一条父记录都具有随机的多条子记录。

CREATE TABLE DB2ADMIN.PARENT_TABLE(PARENT_ID INT NOT NULL, NUM_CHILDREN INT NOT NULL);
INSERT INTO DB2ADMIN.PARENT_TABLE
SELECT ROW_NUMBER() OVER(), SYSFUN.RAND()*5 + 1
FROM SYSCAT.TABLES;
ALTER TABLE DB2ADMIN.PARENT_TABLE ADD PRIMARY KEY(PARENT_ID);

CREATE TABLE DB2ADMIN.CHILD_TABLE(PARENT_ID INT NOT NULL, CHILD_NUM INT NOT NULL);

INSERT INTO DB2ADMIN.CHILD_TABLE
SELECT PARENT_ID, SEQUENCE_TABLE.NUM
FROM DB2ADMIN.PARENT_TABLE
JOIN
(SELECT ROW_NUMBER() OVER() AS NUM
FROM SYSCAT.TABLES) AS SEQUENCE_TABLE
ON AUXILIARY_TABLE.NUM<NUM_CHILDREN;

最后一条 INSERT 语句的结果是,每一条父记录有 1 到 6 条子记录。SEQUENCE_TABLE 是一个表表达式。关于表表达式的更多信息,请查阅 Sheryl Larsen 的文章。

使用辅助表模仿数据倾斜

如果一列中的某些值所出现的频率比其他的要大很多,则该数据存在 数据倾斜(data skew) 。例如:

SELECT CITY, COUNT(*) FROM CUSTOMER
GROUP BY CITY
ORDER BY COUNT(*) DESC

CHICAGO 236
MILWAKEE 95
ROCKFORD 4
NAPERVILLE 3
SPRINGFIELD 3
(snip)

279 rows selected

每当您有理由期望在生产数据中出现数据倾斜时,您就可能需要在测试数据中再现数据倾斜,首先,在一个表中存储预计频率:

CREATE TABLE COLOR_FREQUENCY(COLOR CHAR(10), FREQUENCY SMALLINT);
INSERT INTO COLOR_FREQUENCY VALUES
('RED', 37), ('SILVER',12), ('AMBER', 3), ('GREEN', 3), ('WHITE',2),('BLACK', 1),('BLUE',1);

接着,创建一个辅助表(更明确地说,是一个序列表)。

CREATE TABLE CONSECUTIVE_NUMBER(NUM INT NOT NULL);
INSERT INTO CONSECUTIVE_NUMBER
SELECT ROW_NUMBER() OVER() AS NUM FROM SYSCAT.COLUMNS;

注意: Joe Celko 的 SQL for Smarties 一书中有一章是关于辅助表的。现在,让我们连接这两个表:

SELECT COLOR, FREQUENCY, NUM
FROM COLOR_FREQUENCY JOIN CONSECUTIVE_NUMBER
ON NUM BETWEEN 1 AND FREQUENCY ORDER BY FREQUENCY, COLOR;

COLOR FREQUENCY NUM
---------- --------- -----------
BLACK 1 1
BLUE 1 1
WHITE 2 1
WHITE 2 2
AMBER 3 1
AMBER 3 2
AMBER 3 3
(SNIP)

正如我们所看到的,COLOR_FREQUENCY 表中的每一行都连接了 CONSECUTIVE_NUMBER 表中的 FREQUENCY 行。该示例生成了您需要用于获得所需值分布的确切内容:

CREATE TABLE T_SHIRT(COLOR VARCHAR(30) NOT NULL, SIZE CHAR(1) NOT NULL);

INSERT INTO T_SHIRT
SELECT COLOR, 'M' AS SIZE
FROM COLOR_FREQUENCY JOIN CONSECUTIVE_NUMBER
ON NUM BETWEEN 1 AND FREQUENCY;

SELECT COLOR, COUNT(*) FROM T_SHIRT GROUP BY COLOR;

COLOR 2
------------------------------ -----------
AMBER 3
BLACK 1
BLUE 1
GREEN 3
RED 37
SILVER 12
WHITE 2 ;

因此,T_SHIRT 表现在有 37+12+3+3+2+1+1 = 57 行。该表刚好具有所需的值分布。

为几个列生成具有给定值分布的数据

使用前一章中的所用表,您还可以为 SIZE 列指定值分布:

CREATE TABLE SIZE_FREQUENCY(SIZE CHAR(1), FREQUENCY SMALLINT);
INSERT INTO SIZE_FREQUENCY VALUES
('S', 5), ('M',7), ('L', 9);

并使用两个表表达式来填充 T_SHIRT 表:

INSERT INTO T_SHIRT
SELECT COLOR, SIZE
FROM
(SELECT COLOR FROM COLOR_FREQUENCY JOIN CONSECUTIVE_NUMBER ON NUM BETWEEN 1 AND FREQUENCY) C,
(SELECT SIZE FROM SIZE_FREQUENCY JOIN CONSECUTIVE_NUMBER ON NUM BETWEEN 1 AND FREQUENCY) S

第一个表表达式产生 57 行,而第二个表表达式则产生 5+7+9=21 行。由于我们没有指定任何连接条件,所以第一个结果集中的每一行将会连接第二个中的每一行,从而产生 57*21 行。

注意: 交叉连接可能会生成太多行。因此,该事务将太大,以致服务器无法处理。本例中,您可能需要几个较小一些的 INSERT 语句,例如在第一个 INSERT 中使用以下表表达式:

(SELECT SIZE FROM SIZE_FREQUENCY JOIN CONSECUTIVE_NUMBER ON NUM BETWEEN 1 AND FREQUENCY AND SIZE='L') S

并且在第二个 INSERT 语句中将这个表表达式修改为:

(SELECT SIZE FROM SIZE_FREQUENCY JOIN CONSECUTIVE_NUMBER ON NUM BETWEEN 1 AND FREQUENCY AND SIZE<>'L') S

生成具有相关列的数据

假定我们需要生成几行记录来填充 CAR 表:

CREATE TABLE CAR(
MAKE VARCHAR(20) NOT NULL,
MODEL VARCHAR(20) NOT NULL,
OTHER_DATA VARCHAR(20));

如果尝试前一章中的方法,我们最后将获得一些不可能的 MAKE/MODEL 组合,例如“TOYOTA METRO”和“GEO CAMRY”。该状况称作 MAKE 列和 MODEL 列之间的相关性。正确的方法是指定有效对(MAKE,MODEL)及其频率:

CREATE TABLE MAKE_MODEL_FREQUENCY(MAKE VARCHAR(20), MODEL VARCHAR(20), FREQUENCY SMALLINT);
INSERT INTO MAKE_MODEL_FREQUENCY VALUES
('TOYOTA','CAMRY', 40), ('HONDA','ACCORD',40), ('CHEVY', 'PRIZM', 5), ('GEO','PRIZM', 5),
('CHEVY', 'METRO', 5), ('GEO', 'METRO', 10);

一旦完成该工作,我们就可以按照前面一模一样的方法来连接 CONSECUTIVE_NUMBER 和 MAKE_MODEL_FREQUENCY 表了。

操纵群集因子

表的物理行次序将影响该表上几乎所有查询的性能。因此,所生成的数据具有理想的物理行次序是极其重要的。如果您期望一个索引具有较高的群集因子,就只要重组该索引上的表。相反,如果您期望该索引具有较低的群集因子,也可以容易地以随机次序来打乱该表的次序,从而使得该索引的群集因子接近于 0:

CREATE TABLE NAMES(
FULL_NAME VARCHAR(50) NOT NULL,
ORDERED_ON INT);

INSERT INTO NAMES(FULL_NAME, ORDERED_ON)
SELECT TABNAME || ', ' || COLNAME AS FULL_NAME,
SYSFUN.RAND() * 10000 AS ORDERED_ON
FROM SYSCAT.COLUMNS;

CREATE INDEX NAMES_FULL_NAME ON NAMES(FULL_NAME);
CREATE INDEX NAMES_ORDER ON NAMES(ORDERED_ON);
REORG TABLE DB2ADMIN.NAMES INDEX DB2ADMIN.NAMES_ORDER;
RUNSTATS ON TABLE DB2ADMIN.NAMES AND DETAILED INDEXES ALL;

在进行重组之后,索引 NAMES_FULL_NAME 将具有一个极低的群集因子(接近于 0),因为现在的行是以随机次序存储的。

注意: 还可以重组该表,以使索引 NAMES_FULL_NAME 的群集因子接近 0 到 1 之间的任何给定值,但是,该内容超出了本文的范围。

结束语:

本文讨论了如何构建一个测试数据集,以使该数据集达到用于测试的规模,并且具有期望的值分布和列间相关性。

LoadRunner函数中文翻译系列之二--Check(1)

2009年09月26日 星期六上午 10:03

web_find
语法:
int web_find (const char *StepName, <Attributes and Specifications list>, char *searchstring, LAST );

参数:
1、StepName:步骤名称,在Tree视图中出现。

2、Attributes and Specifications list:

支持的属性有:

Frame:在多Frame的情况下,定义要查找Frame的范围。

Expect:定义在什么情况下函数检查成功:找到了指定的搜索标准或者没有找到。例如说,可以检查指定的错误信息是否出现在web页面中。合法的值有2个:found和notfound。默认值是“found”。

Matchcase:指定搜索是否区分大小写。

Repeat:指定当第一次发现要查找的字符串时,搜索是否继续。当一个web页面中包含多个被查找的字符串时,此参数是非常有用的。合法的值有2个:yes,no。默认值是“yes”。

Report:指定在什么情况下,VuGen在执行日志中显示此函数的检查结果。合法的值有:success,failure,always。默认值是“always”。

Onfailure:此参数决定在函数检查失败后,Vuser是否中断。参数值是abort。如果指定了Onfailure=abort,当函数检查失败时,不论在运行时设置中的error-handling是什么,脚本都会中断。

如果没有指定Onfailure=abort,那么运行时设置中error-handling将会起作用。

支持的特性有:RightOf, LeftOf (不支持7.x及更高版本)。

RightOf:要查找的字符串右边的内容。

LeftOf:要查找的字符串左边的内容。

3、Searchstring:需要查找的字符串,格式为“What=stringxyz”。此搜索不区分大小写。

4、LAST:属性列表结束符。

返回值
整型。 成功时返回LR_PASS(0),失败时返回LR_FAIL (1)。

说明
此函数的作用是在HTML页面中查找指定的字符串。

此函数只能在基于HTML录制的脚本中使用。当指定的HTML请求全部完成以后,开始执行搜索过程,比web_reg_find要慢。

web_find函数在C语言的脚本中已经被web_reg_find所替代,web_reg_find运行速度比较快,而且在HTML-based和URL-based的录制方式中都可以使用。 在C语言脚本中,web_find是向后兼容的。Java和Visual Basic脚本中不再支持它。

运行在HTTP模式下的WAP用户都和运行在WSP回放模式下的WAP用户都不支持此函数。

web_global_verification
语法:
int web_global_verification (<List of Attributes>, LAST );

参数:
List of Attributes:

1、Text:此属性是一个非空的,以NULL结尾的字符串,表示要查找的内容。语法是”Text=string”。还可以使用text flags自定义字符串。

2、TextPfx:没有指定Text的情况下使用此属性。要查找的字符串的前缀。语法是” TextPfx =string”。还可以使用text flags自定义字符串。

3、TextSfx:没有指定Text的情况下使用此属性。要查找的字符串的后缀。语法是” TextSfx =string”。还可以使用text flags自定义字符串。

4、Search:可选项,在哪里查找字符串。可选的值是:Headers,Body,NORESOURCE或All。默认值是NORESOURCE。语法是“Search=value”。

5、Fail:当字符串找不到时的处理选项:Found (默认值)或NotFound。Found表示当找到对应的字符串时发生了错误(例如“Error”)。NotFound表示当找不到字符串时发生了错误。语法是“Fail=value“。

6、ID:在日志文件中标识当前函数。

LAST:属性列表结束符。

注:text flags:/IC表示忽略大小写;/BIN表示指定的是二进制数据。

返回值
整型。 成功时返回LR_PASS(0),失败时返回LR_FAIL (1)。

说明
web_global_verification属于注册函数,注册一个在web页面中搜索文本字符串的请求,与web_reg_find只在下一个Action函数中执行搜索不同的是,它是在之后所有的Action类函数中执行搜索的。可以搜索页面的body,headers,html代码或者是整个页面。

在检测一些应用程序级别(不通过http状态码来表现)的错误时,web_global_verification是非常有用的。如果要定位通过HTTP状态码表现的错误时,使用web_get_int_property。

查找范围:all:这个HTML页面;Headers:页面的头;body:页面的体,包含所有的资源但不包含头;NORESOURCE(默认选项):仅仅包含页面的体,把包括头和资源。

如果不知道要查找的精确的文本,或者要查找的多个文本不是完全相同的,可以使用前缀和后缀来表示。这时需要用到TextPfx和TextSfx属性。这2个属性必须同时指定,一旦指定了其中一个,就不能指定Text属性了。

注意:web_global_verification在WAP协议下不能运行。

web_image_check
语法:
int web_image_check(const char *CheckName, <List of Attributes>, <"Alt=alt"|| "Src=src">, LAST );

参数:
1、CheckName:名称,在Tree视图中出现。

2、List of Attributes:

支持的属性有:Frame(在多Frame的情况下,定义要查找Frame的范围)。

支持的选项有:expect, matchcase, repeat, report, onfailure。

Tip:选项跟属性的区别,大部分选项都只允许设置预定义的值,其他的值都是无效的。

3、Alt:检查图象的ALT标记。不允许空值。

4、Src:检查图象的SRC标记。不允许空值。

5、LAST:参数列表结束的指示符。

返回值
整型。

说明
web_image_check检查指定的图象是否在HTML页面中出现。

Alt或者Src两者必须有一个在参数列表中出现。如果两项都通过,那么检查成功。

此函数仅仅支持基于HTML的脚本。

LoadRunner函数中文翻译系列之三--Concurrent Group

2009年09月26日 星期六上午 10:04

web_concurrent_start
语法:
int web_concurrent_start ( [char * ConcurrentGroupName,] NULL );

参数:
ConcurrentGroupName:可选的,并发组的标识符。

NULL:参数列表结束的标记符。

返回值
整型。返回LR_PASS (0)表示成功,返回LR_FAIL (1)表示失败。

说明
web_concurrent_start函数是并发组开始的标记。组中所有的函数是并发执行的。并发组的结束web_concurrent_end 函数。在并发组中,可以包含的函数有:web_url、web_submit_data、web_custom_request、web_create_html_param、web_create_html_param_ex、web_reg_save_param、web_add_header。

在并发组中的函数不是立即执行的。在并发组开始时,所有的函数首先被记录下来,当并发组结束时,所有的函数并发执行。

所有的Web 用户,HTTP模式下的WAP用户持本函数。运行在Wireless Session Protocol(WSP)回放模式下的WAP虚拟用户,不支持本函数。

web_concurrent_start
语法:
int web_concurrent_end ( reserved );

参数:
reserved:保留的供扩展的字段。

返回值
整型。返回LR_PASS (0)表示成功,返回LR_FAIL (1)表示失败。

说明
web_concurrent_end,并发组结束的标记。脚本执行时,碰到 web_concurrent_end函数时,开始并发执行所有记录的函数。

在并发组中的函数不是立即执行的。在并发组开始时,所有的函数首先被记录下来,当并发组结束时,所有的函数并发执行。

可以并发执行的函数的个数是有限制的,使用运行时设置-Netword标签页的Concurrent Connection来设置。

LoadRunner之协议选择

2009年09月26日 星期六上午 10:08

在学习LoadRunner协议选择之前,我觉得我们有必要了解一下协议的基本概念。首先我们知道,计算机与计算机之间的通信都离不开通信协议,接着我们来说说通信协议的概念。通信协议是什么,通信协议实际上是一组规定和约定的集合。说白了就是两台或者多台计算机在通信时必须约定好本次通信做什么,例如是进行文件传输,还是发送电子邮件;然后约定怎样通信,什么时间通信等。因此,通信双方要遵从相互可以接受的协议(相同或兼容的协议)才能进行通信,如目前因特网上广泛使用的TCP/IP协议等,任何计算机连入网络后只要运行TCP/IP协议,就可访问因特网。

了解了协议的基本概念和作用之后,我们来说说LoadRunner的协议选择。LoadRunner首先是一个测试工具,其次是一个性能测试工具,然后是该工具是一个基于协议,也就是说LoadRunner测试的对象都需要使用通信协议,对于那些不使用通信协议仅仅进行本地处理的软件例如Microsoft Word,LoadRunner就不适用。

说到通信协议我们来熟悉一下协议的分层,按照OSI的分层模型,分层结构如下:

OSI七层模型
TCP/IP协议
应用层
应用层(Application)
表示层
会话层
传输层
传输层(Transport)
网络层
网络层(Internet)
数据链路层
网络接口层(Network)
物理层

按照TCP/IP协议的分层,分层结构如下:

TCP/IP协议
对应的服务
应用层
WWW、SMTP、FTP、Telnet、Gopher、SNMP
Socket、NetBIOS
传输层
TCP、UDP
网络层
IP(ARP、RARP、ICMP)
网络接口层
Ethernet、X.25、PPP、SLIP

第一个分层是由OSI制定但不实用,后一个是目前广泛使用且被业界认做既定标准的协议分层,下文探讨的LoadRunner协议选择即按TCP/IP协议的分层模型讨论。

接着来说说LoadRunnerVuGen中的协议分类,VuGen(LR8.1)中的协议分类如下表所示:

应用程序部署解决方案
Citrix ICA
客户端/ 服务器
DB2 CLI、DNS、Informix、MS SQL Server、ODBC、Oracle(2 层)、Sybase Ctlib、Sybase Dblib 和 Windows Sockets 协议
自定义
C 模板、Visual Basic 模板、Java 模板、Javascript 和 VBScript 类型的脚本。
分布式组件
适用于 COM/DCOM、Corba-Java 和 Rmi-Java 协议。
电子商务
FTP、LDAP、Palm、PeopleSoft 8 mulit-lingual、SOAP、Web(HTTP/HTML) 和双 Web/WinSocket 协议。
Enterprise Java Bean
EJB 测试和 Rmi-Java 协议。
ERP/CRM
Baan、Oracle NCA、Peoplesoft-Tuxedo、SAP-Web、SAPGUI、Siebel-DB2 CLI、Siebel-MSSQL、Siebel-Web 和 Siebel-Oracle 协议
传统
终端仿真 (RTE)。
邮件服务
Internet 邮件访问协议 (IMAP)、MS Exchange (MAPI)、POP3 和SMTP。
中间件
Jacada 和 Tuxedo (6、7)协议。
流数据
Media Player (MMS) 和 Real 协议。
无线
i-Mode、VoiceXML 和 WAP 协议。

仔细研究发现LoadRunner VuGen中的协议与文章开头所说的通信协议还是有一定的区别的,例如像LoadRunner VuGen中的C 模板、Visual Basic 模板、Java 模板、Javascript 和 VBScript 类型的脚本均为开发语言,非通信协议,但LoadRunner即把它列在这儿,我们也就暂且认可。

了解了LoadRunner的协议类型之后,我们进入正式话题,即测试时如何选择协议。

正式测试之前,测试人员都需要预先熟悉被测对象,我们需要知道我们的被测对象是一个什么样的结构,是B/S结构还是C/S结构,了解这个之后,我们还需要了解被测对象所使用的协议是什么,也许有的人说我们的程序使用的是TCP/IP协议,其实他的回答跟我们需要知道的差别很大,因为我们知道,所有的通信软件都需要使用TCP/IP协议,为什么呢,因为这个协议是底层协议,所有应用层数据都必须经过这个协议封装之后才能向更底一层传输。我们需要知道的是被测对象在应用层使用的是什么协议,就像我们使用邮件客户端发送邮件一样,我们知道使用的应用层协议是SMTP,使用邮件客户端接收邮件时使用的时POP3协议。了解上述信息之后,我们的定位也就准确了,也就是说在LoadRunner中所说的协议基本上都是应用层协议(也有底层协议,例如 Windows Sockets),知道这点之后,我们在询问开发人员时就避免了不少麻烦,省的开发人员告诉你我们使用的是TCP/IP协议或者其他底层协议。

了解了LoadRunner中的协议之后,我们就进入协议确定阶段,协议的确定,通常有如下几种方法:

1、通过询问开发人员获知所使用的协议,通常这是最简单也是最直接的方法;因为没有人比开发人员更清楚他们所开发的应用程序使用的什么通信协议了;

2、通过概要或详细设计手册获知所使用的协议,在没有开发人员支持的情况,通过概要设计或详细设计获知所使用的协议不失为第二简便方法;

3、通过协议分析工具捕包分析,然后确定被测对象所使用的协议。在使用协议分析工具分析协议过程当中一定要摒除底层协议,不要被底层协议所迷惑;

4、通过以往测试经验确定被测对象所使用的协议,当然通过这种方法确定的协议有一定的不准确性;

通过以上四种方法我们基本就确定了录制时应该选择什么协议,光确定协议是没有用的,最主要的是付诸行动,确定了协议之后,我们进入VuGen开始录制脚本,录制完成后看看是否生成相应脚本,如果脚本内容为空可能我们选择的协议不正确,我们可以尝试选择其他协议。

一般来说协议选择有如下原则:

B/S结构,选择WEB(Http/Html)协议;

C/S结构,可以根据后端数据库的类型来选择,如SybaseCTLib协议用于测试后台的数据库为Sybase的应用;MS SQL Server协议用与测试后台数据库为SQL Server的应用;对于一些没有数据库的Windows应用,可选用Windows Sockets底层协议;使用了数据库但使用的是ODBC连接的数据则选择ODBC协议;

对于有些使用纯JAVA编写的C/S结构的东东,采用JAVA,而且不能录制只能手工编写代码(工作量和难度还是有的)。同样不能录制的还包括C、VB Script、VB、VBNet User协议。

对于Windows Sockets协议来说,最适合的那些基于Socket开发的应用程序;但是由于网络通讯的底层都是基于Socket的,因此几乎所有的应用程序都能够通过Socket来录制,哪可能有人会问,哪既然Socket都能录制下来,还要那么多协议做什么,价格还贼贵,其实最主要的原因就是Socket录制的代码可读性较差,如果Socket的脚本可读性较高的话,实话就没有其他协议出现的必要性了。

对于邮件来说,首先要看你收邮件的途径,如果你通过WEB页面收发邮件,毫无疑问,你选择协议时就需要选择HTTP协议,如果你通过邮件客户端,像OutLook、FoxMail之类的,则需要根据操作不同选择不同的协议了,例如发邮件你可能要选择SMTP、收邮件你可能需要选择POP3。

LR中常用的C函数

2009年09月26日 星期六上午 10:09

LR中常用的C函数

char *strcat ( char *to, const char *from );
功能:链接两个字符串。
例子:
这个例子是用strcat链接字符串:zee和slo@hotmail.co
脚本如下:
    char test[1024], *a = "slo@hotmail.com";
    strcpy(test, "zee");
    strcat(test, a);
    lr_output_message("We can see %s",test);
运行后在executon log中看到如下语句:
Starting action Action.
Action.c(16): We can see zeeslo@hotmail.com
2    strchr
char *strchr ( const char *string, int c );
功能:返回字符串中指定字符后面的字符串。
例子:
这个例子是返回第一个出现e字符以后所有的字符,和最后一次出现e字符以后所有的字符。
脚本如下:
    char *string = "Zee is a tester";
    char *first_e, *last_e;
    first_e = (char *)strchr(string, 'e');
    lr_output_message("We can see the first occurrence of e: %s",first_e);
    last_e = (char *)strrchr(string, 'e');
    lr_output_message("We can see the last occurrence of e: %s", last_e);
运行后在executon log中看到如下语句:
Starting action Action.
Action.c(12): We can see the first occurrence of e: ee is a tester
Action.c(14): We can see the last occurrence of e: er
3    Strcmp&stricmp
int strcmp ( constchar *string1, const char *string2 );大小写敏感。
int stricmp ( const char *string1, const char *string2 );大小写不敏感。
功能:比较字符串。
例子:
按是否区分大小写对比两个字符串,并打印出它们的大小关系。
脚本如下:
    int result;
    char tmp[20];
    char string1[] = "We can see the string:ZEE";
    char string2[] = "We can see the string:zee";
    result = strcmp( string1, string2 ); /*区分大小写,比较字符串 */
    if( result > 0 )
      strcpy( tmp, "大于" );
    else if( result < 0 )
      strcpy( tmp, "小于" );
    else
      strcpy( tmp, "等于" );
    lr_output_message( "strcmp: String 1 %s string 2", tmp );
    result = stricmp( string1, string2 ); /* 不区分大小写,比较字符串 */
    if( result > 0 )
      strcpy( tmp, "大于" );
    else if( result < 0 )
      strcpy( tmp, "小于" );
    else
      strcpy( tmp, "等于" );
    lr_output_message( "stricmp: String 1 %s string 2", tmp );    
运行后在executon log中看到如下语句:
Starting action Action.
Action.c(22): strcmp: String 1 小于 string 2
Action.c(33): stricmp: String 1 等于 string 2
4    strcpy
char *strcpy ( char *dest, const char *source );
功能:复制一个字符串到另一个字符串中。
例子:
复制一个字符串到字符数组中,并打印出来。
脚本如下:
    char test[1024];
    strcpy(test, "what can we see?    ");
    lr_output_message("%s", test);
运行后在executon log中看到如下语句:
Starting action Action.
Action.c(10): what can we see?   
5    Strdup& strlwr
char *strdup ( const char *string );
复制一个字符串。
char *strlwr ( char *string );
转换成小写字母。
例子:
在这个例子中,Vuser的组名被转换为小写字母。但是lr_whoami把组名作为静态buffer返回。这样的buffer不能被操作。如果有操作需要,就复制这个静态buffer。
脚本如下:
    int id;
    char *groupname_static, *groupname;
    /* 从VuGen中得到组名 */
    lr_whoami(&id, &groupname_static, NULL);
    lr_output_message("groupname=%s", groupname_static);
    /*复制这个静态组名以便我们可以操作它 */
    groupname = (char *)strdup(groupname_static);
    groupname = (char *)strlwr(groupname);
    lr_output_message("lower case groupname=%s", groupname);
    free(groupname);
上述脚本用vugen保存为:CHANGE
在controller中运行(设置为总是发送消息)
运行后在log中看到如下语句:
Starting action Action. [MsgId: MMSG-15919]
Action.c(11): groupname=CHANGE     [MsgId: MMSG-17999]
Action.c(16): lower case groupname=change    [MsgId: MMSG-17999]
6    Strlen
size_t strlen ( constchar *string );
功能:返回字符串长度(bytes).
例子:
这个例子很简单,就是得到一个字符串中的字符的个数。然后打印出来。
脚本如下:
    char *str = "Zee is a tester";
    unsigned int len;
    len = strlen(str);
    lr_output_message("The sentence has %d letters",len);
运行后在log中看到如下语句:
Action.c(13): The sentence has 15 letters
7    Strncat
char *strncat ( char *to_string, const char *from_string, size_t n );
把一个字符串连接到另一个字符串后面。
例子:
在这里,我随便写了两个字符串,用此函数把他们连接起来,并打印出来。
脚本如下:
char str1[]="Zee is ";
char str2[]="a tester.";
lr_output_message("What can we see?");
lr_output_message("The str1 is %s.",str1);
strncat(str1,str2,20);
lr_output_message("The str1 is %s.",str1);
运行后在log中看到如下语句:
Action.c(9): What can we see?
Action.c(10): The str1 is Zee is .
Action.c(13): The str1 is Zee is a tester..
注:我们可以看到,没有连接前的str1是:Zee is,连接后的字符串是:Zee is a tester。也可以看看strcat函数。
8    strncmp
int strncmp ( constchar *string1, const char *string2, size_t n );
对比两个字符串的前n位。
例子:
对比两个字符串,并把对比结果打印出来。这里我和上面的strcmp一起写。
脚本如下:
char result;
char str1[]="Zee is a tester.";
char str2[]="Zee is a tester.";
char str3[]="zee is a tester?";
result = strcmp(str1,str2);
if(result > 0)
      lr_output_message("str1 is greater than str2.");
else if(result < 0)
      lr_output_message("str1 is less than str2.");
else
      lr_output_message("str1 is equal to str2.");
result = strncmp( str1, str3 , 30);
if(result > 0)
      lr_output_message("str1 is greater than str3.");
else if(result < 0)
      lr_output_message("str1 is less than str3.");
else
      lr_output_message("str1 is equal to str3.");
运行后在log中看到如下语句:
Starting iteration 1.
Starting action Action.
Action.c(18): str1 is equal to str2.
Action.c(28): str1 is less than str3.

LR字符串与参数的操作及转换技巧

2009年09月27日 星期日下午 03:01

刚开始学LR时,经常搞不清楚变量和参数的区别与用法,最近在一次脚本编写中,整理出来的一些小技巧,与大家一起分享。

//字符串复制
        strcpy(str,"Hello ") ;

        //字符串连接
        strcat(str,"World !");
        lr_message("str: %s",str);

        //变量转为参数,将变量str的值存到参数Param中
        lr_save_string(str,"Param");

        //参数复制
        lr_save_string(lr_eval_string("{Param}"),"Param_1");

        //参数转为变量
        strcpy(str1,lr_eval_string("{Param_1}"));
        lr_message("str1: %s",str1);

        //参数名称格式化输出到变量中
        sprintf(str2,"{Param_%d}",1);
        lr_message("str2: %s",lr_eval_string(str2));

运行结果:
        str: Hello World !
        vuser_init.c(14): Notify: Saving Parameter "Param = Hello World !"
        vuser_init.c(19): Notify: Parameter Substitution: parameter "Param" = "Hello World !"
        vuser_init.c(19): Notify: Saving Parameter "Param_1 = Hello World !"
        vuser_init.c(24): Notify: Parameter Substitution: parameter "Param_1" = "Hello World !"
        str1: Hello World !
        vuser_init.c(30): Notify: Parameter Substitution: parameter "Param_1" = "Hello World !"
        str2: Hello World !

查看文章

   
         

AS3及Flex的百条常用知识

2009年10月10日 星期六下午 03:07

【改变输出swf的尺度,背景颜色或帧频】
在"Navigator"窗框里右键你的项目>选中"Properties">选中"ActionScript Compiler">在"Additional compiler arguments"里输入你所需要的命令
如想改变背景颜色,请输入: -default-background-color 0xffffff

【鼠标坐标】
mouseX mouseY

【检查变量类型并返回布尔值】
is

【检查变量类型并返回类型】
typeof

【检查对象类型并返回该对象】
as

【是数字但不是有效数字问题】
var quantity:Number = 15 - "rabbits";
trace(typeof quantity); //显示: "number" , 但它是NaN (not a number)
trace(quantity is Number); //true
trace(quantity != NaN); //false
//使用isNaN()函数检测:
isNaN(quantity); //true
//检测变量是否内含有效数字:
!isNaN(quantity); //false

【取消默认的严格编译模式】
在"Navigator"窗框里右键你的项目>选中"Properties">选中"ActionScript Compiler">取消"Enabel compile-time type checking"选项

【基元数据类型和复杂数据类型好比"值类型"和"引用类型"】
基元数据类型类似按值传递:
var intOne:int = 1;
var intTwo:int = 1;
trace(intOne == intTwo); //true

【复杂数据类型类似按引用传递】
var arrayOne:Array = new Array("a", "b");
var arrayTwo:Array = arrayOne;
trace(arrayOne == arrayTwo); //true
//-----------------------------------
var arrayOne:Array = new Array("a", "b");
var arrayTwo:Array = new Array("a", "b");
trace(arrayOne == arrayTwo); //false

【优化逻辑AND(&&)和OR(||)的小知识】
对于逻辑And(&&):
除非条件表达式的前半部分为真,否则,ActionScript不会再去求算逻辑AND运算符的后半部.如果前半部为假,整个条件表达式一定为假,所以再去求算后半部就没效率了.
对于逻辑OR(||):
除非条件表达式前半部为假,否则,ActionScript不会再去求算逻辑OR运算符的后半部,如果前半部为真,整个条件表达式一定为真.
总结:使用逻辑AND(&&)时,把结果最可能为false的表达式放到前面;使用逻辑OR(||)时,把结果最可能为true的表达式放到前面.

【Timer类注意事项】
不要认为Timer可以极其准确;使用Timer时间间隔不要低于10毫秒.

【private,protected,internal,public访问权限】
private:只能在类本身内部访问,按惯例,命名私有成员时以下划线"_"开头;
protected:可以由类本身或任何子类访问.但这是以实例为基础的.换言之,类实例可以访问自己的保护成员或者父类的保护成员,但不能访问相同类的其它实例的保护成员,按惯例,命名保护成员时以下划线"_"开头;
internal:可以由类本身或者相同包内的任何类访问;
public:可以在类内部访问,也可以由类实例访问,或者声明为static时,可以直接从类访问.

【一个函数具有未知个数的参数,用arguments对象或"...(rest)"符号访问它的参数】
注意:使用"...(rest)"参数会使 arguments 对象不可用;
private funciton average():void{
trace(arguments.length); //输出参数的个数
// arguments的类型是:object,但可以像访问数组一样去访问它
trace(arguments[1]); //输出第二个参数
}
private function average(...argu):void{
trace(argu[1]); //输出第二个参数,argu参数名是自定义的.
}

【错误处理try,catch,finally】
private function tryError():void{
try {
trace("测试开始-try");
throwError();
}catch(errObject:Error) {
trace("错误信息:" + errObject.message);
trace("测试结束-catch");
return;
}finally{
trace("虽然catch里已经有return方法,但位于return方法后面的finally里的代码依然会被执行.其实无论return方法是在try里,还是catch里,finally里的代码始终会被执行");
}
trace("前面已经有return了,此处是不会再执行的.除非没有抛出错误,以使catch里的代码没有被执行");
}
private function throwError():void{
throw new Error("抛出错误");
}

【for...in与for each...in的区别】
与for...in循环不同的是,for each...in循环中的迭代变量包含属性所保存的值,而不包含属性的名称(或主键,索引).

【命名包路径的小技巧】
使用相应于拥有者和相关项目的包名称会比较好.按惯例来讲,包名称的开头应该是逆向的网址名称.例如,如果Example Corp(examplecorp.com)写了一些ActionScript3.0类,就会把所有类放在com.examplecorp包内(或者 com.examplecorp的子包内).如此一来,如果英国有另一家Example Corp(examplecorp.co.uk)也写了一些ActionScript3.0类,只要使用包uk.co.examplecorp,就可确保唯一性.
当类属于特定应用程序的一部分时,就应该放在该应用程序特定的子包内.例如,Example Corp可能有个应用程序名叫WidgetStore.如果WidgetStore应用程序使用一个名为ApplicationManager的类,则此类就应该放在com.examplecorp.widgetstore包内,或者位于该包的子包内.
按惯例来说,包名称的开头是小写字母.

【隐式的取出方法(getter)和设定方法(setter)】
public function get count():uint {
return _count;
}
public function set count(value:uint):uint {
if(value < 100){
_count = value;
}else {
throw Error();
}
}

【确保类是绝不会有子类,使用final】
final public class Example{}

【super关键字的使用】
super(); //父类的构造函数,只能在类实例构造函数内部使用
super.propertyName; //调用父类的属性,属性需要声明为public或protected
super.methodName(); //调用父类的方法,方法需要声明为public或protected

【建立常数,使用关键字const而不是var】
static public const EXAMPLE:String = "example";

【检测播放器版本】
flash.system.Capabilities.version
对于8.5版以前的任何Flash Player版本,这种方法都不适用.

【判断客户端系统】
flash.system.Capabilities.os

【检测播放器类型】
flash.system.Capabilities.playerType
可能的值有:
"StandAlone",用于独立的 Flash Player
"External",用于外部的 Flash Player 或处于测试模式下
"PlugIn",用于 Flash Player 浏览器插件
"ActiveX",用于 Microsoft Internet Explorer 使用的 Flash Player ActiveX 控件

【检测系统语言】
flash.system.Capabilities.language

【判断用户是否启用了IME(输入法编辑器)】
flash.system.IME.enabled

【检测屏幕的分辨率】
flash.system.Capabilities.screenResolutionX
flash.system.Capabilities.screenResolutionY

【把弹出窗口居中的算法】
X = (舞台宽/2)-(窗口宽/2)
Y = (舞台高/2)-(窗口高/2)

【控制影片配合Player的方式,包括缩放问题】
stage.scaleMode
可供选择值:flash.display.StageScaleMode

【舞台的对齐方式】
stage.align
可供选择值:flash.display.StageAlign

【隐藏Flash Player的右键菜单】
stage.showDefaultContextMenu = false;

【检测系统是否具有音频功能】
flash.system.Capabilities.hasAudio

【检测播放器是在具有MP3解码器的系统上运行,还是在没有MP3解码器的系统上运行】
flash.system.Capabilities.hasMP3

【检测播放器能 (true) 还是不能 (false) 播放流式视频】
flash.system.Capabilities.hasStreamingVideo

【检测播放器是在支持 (true) 嵌入视频的系统上运行,还是在不支持 (false) 嵌入视频的系统上运行】
flash.system.Capabilities.hasEmbeddedVideo

【检测播放器能 (true) 还是不能 (false) 对视频流(如来自 Web 摄像头的视频流)进行编码】
flash.system.Capabilities.hasVideoEncoder

【显示 Flash Player 中的"安全设置"面板】
flash.system.Security.showSettings();
可供选择项:flash.system.SecurityPanel

【让其它域的.swf访问本域的.swf】
在本域的.swf文件里加上:flash.system.Security.allowDomain()
或 者使用安全策略文件"crossdomain.xml".在Flash 8以前,这个文件必须放在.swf所在域的根目录,现在,你可以使用flash.system.Security.loadPolicyFile(),指定安全策略文件所在的位置.拒绝任何域的做法是在<cross-domain-policy>标签内什么也不填,安全策略文件也支持通用字符 "*":
<?xml version="1.0"?>
<!-- http://www.mydomain.com/crossdomain.xml -->
<cross-domain-policy>
<allow-access-from domain="www.riahome.cn " />
<allow-access-from domain="*.Y-boy.cn" />
<allow-access-from domain="210.38.196.48" />
<allow-access-from domain="*" />
</cross-domain-policy>

【数字的不同进制之间的转换】
parseInt(str:String, radix:uint = 0):Number 返回十进制的数,参数radix表示要分析的数字的基数.如果省略radix,就默认为10,除非字符串的开头是"0x","0X"或"0":
trace(parseInt("0x12")); //设定radix为16,输出:18
trace(parseInt("017")); //设定radix为8,输出:15
或者使用Number,uint和int对象的toString(radix)方法.

【使用Math.round()对一个数取整,四舍五入】
Math.round()
trace(Math.round(204.499)); //输出:204
trace(Math.round(401.5)); //输出:402

【使用Math.floor()对一个数向下取整,就是只要整数部分而不理会小数分】
trace(Math.floor(204.99)); //输出:204

【使用Math.ceil()对一个数向上取整,只要小数部分不为零,整数部分就加1】
trace(Math.ceil(401.01)); //输出:402

【产生一个随机数】
使用Math.random()产生一个伪随机数n,其中 0 <= n < 1

【把数字取至最近的小数点位,即指定精确度】
1. 决定你要取的数字的小数点位数:例如,如果你想把90.337取成90.34,就表示你要取到两位小数点位,也就是说你想取至最近的0.01;
2. 让输入值除以步骤1所选的数字(此例为0.01);
3. 使用Math.round()把步骤2所计得的值取成最近的整数;
4. 把步骤3所得的结果乘以步骤2用于除法的那个值.
例如,要把90.337取成两个小数点位数,可以使用:
trace(Math.round(90.337/0.01)*0.01); //输出:90.34

【把数字取成一个整数的最接近倍数值】
例1,这样会把92.5取成5的最近倍数值:
trace(Math.round(92.5/5)*5); //输出:95
例2,这样会把92.5取成10的最近倍数值:
trace(Math.round(92.5/10)*10); //输出:90

【在指定数值范围内获得随机数】
//可取范围:[min, max]
private function randRange(min:Number, max:Number):Number {
var randomNum:Number = Math.floor(Math.random() * (max - min + 1)) + min;
return randomNum;
}
应用例子:
模拟投银币,即希望得到随机布尔值(true 或 false): randRange(0, 1);
模拟投骰子,即希望得到随机六个值: randRange(1, 6);
为避免被缓存而需要产生一个独一无二的数字追加在URL尾端,通常最佳方法是取得当前毫秒数.

【弧度(radian)与度数(degree)之间的转换】
从弧度转为度数: degrees = radians * 180 / Math.PI
从度数转为弧度: radians = degrees * Math.PI / 180

【计算两点之间的距离】
勾股定理: c2 = a2 + b2
假设有两个影片剪辑mc1和mc2,则它们两点间的距离c为:
var c:Number = Math.sqrt(Math.pow(mc1.x - mc2.x, 2) + Math.pow(mc1.y - mc2.y, 2));

【模拟圆周运动】
已知圆心o(x0, y0),半径r和弧度angle,求圆上任意一点P(x, y)的坐标:
x = x0 + (Math.cos(angle) * r);
y = y0 + (Math.sin(angle) * r);
注意:舞台的x轴正方向水平向右,y轴正方向垂直向下.

【模拟椭圆运动】
已知圆心o(x0, y0),长轴a,短轴b以及弧度angle,求圆上任意一点P(x, y)的坐标:
x = x0 + (Math.cos(angle) * a);
y = y0 + (Math.sin(angle) * b);

【华氏温度和摄氏温度之间的转换】
华氏温度 = 摄氏度数 * 9 / 5 + 32
摄氏温度 = (华氏度数 - 32) * 5 /9

【公斤与磅之间的转换】
公斤 = 磅 * 2.2
磅 = 公斤 / 2.2

【向数组尾端添加元素】
var array:Array = new Array();
array.push("a", "b");
//向数组尾端添加单一元素也可以这样:
array[array.length] = "c";
//如果以索引设定的元素不存在,数组本身会自动扩展以包含足够的元素数目.介于中间的元素会被设为undefined:
array[5] = "e";
trace(array[4]); //输出: undefined

【向数组开端添加元素】
var array:Array = ["a", "b"];
array.unshift("c", "d");
trace(array); //输出: c,d,a,b

【删除数组中第一个元素并返回该元素,使用shift()方法】
var letters:Array = new Array("a", "b", "c");
var firstLetter:String = letters.shift();
trace(letters); //输出: b,c
trace(firstLetter); //输出: a

【删除数组中最后一个元素并返回该元素的值,使用pop()方法】
var letters:Array = new Array("a", "b", "c");
trace(letters); //输出: a,b,c
var letter:String = letters.pop();
trace(letters); //输出: a,b
trace(letter); //输出: c

【删除数组中的元素,给数组添加新元素并返回删除的元素,使用splice()方法】
splice(startIndex:int, deleteCount:uint, ... values):Array
startIndex: 一个整数,它指定数组中开始进行插入或删除的位置处的元素的索引;
deleteCount: 一个整数,它指定要删除的元素数量;
... values: 用逗号分隔的一个或多个值的可选列表或数组,此列表或数组将插入到此数组中由 startIndex 参数指定的位置.

【查找数组中第一个相匹配的元素】
var array:Array = ["a", "b", "c", "d", "a", "b", "c", "d"];
var match:String = "b";
for(var i:int = 0; i < array.length; i++) {
if(array[i] == match) {
trace("Element with index " + i + " found to match " + match);
//输出: Element with index 1 found to match b
break;
}
}

【查找数组中最后一个相匹配的元素】
var array:Array = ["a", "b", "c", "d", "a", "b", "c", "d"];
var match:String = "b";
for(var i:int = array.length - 1; i >= 0; i--) {
if(array[i] == match) {
trace("Element with index " + i + " found to match " + match);
//输出: Element with index 5 found to match b
break;
}
}

【把字符串转成数组】
使用String.split()方法:
var list:String = "I am YoungBoy.";
var words:Array = list.split(" "); //以空格作为分隔符将字符串切割
trace(words); //输出: I,am,YoungBoy.

【把数组转成字符串】
使用String.join()方法:
var myArr:Array = new Array("one", "two", "three");
var myStr:String = myArr.join(" and ");
trace(myArr); //输出: one,two,three
trace(myStr); //输出: one and two and three

【使用对象数组处理相关数据】
var cars:Array = new Array();
cars.push({make:"Mike", year:1997, color:"blue"});
cars.push({make:"Kelly", year:1986, color:"red"});
for(var i:int = 0; i < cars.length; i++) {
trace(cars[i].make + " - " + cars[i].year + " - " + cars[i].color);
}
//输出:
//     Mike - 1997 - blue
//     Kelly - 1986 - red

【在数组中获取最小或最大值】
var scores:Array = [10, 4, 15, 8];
scores.sort(Array.NUMERIC);
trace("Minimum: " + scores[0]);
trace("Maximum: " + scores[scores.length - 1]);

【使用for ... in语句读取关联数组元素】
var myObject:Object = new Object();
myObject.name = "YoungBoy";
myObject.age = 20;
for(var i:String in myObject) {
trace(i + ": " + myObject[i]);
}
//输出: name: YoungBoy
//       age: 20
注意: for ... in循环不会显示对象所有的内建属性.例如,循环会显示执行期间新增的特殊属性,但是,不会列出内建对象的方法,即使都是储存在对象属性内.

【AVM(ActionScript Virtual Machine,虚拟机)和渲染引擎(Rendering Engine)】
AVM负责执行ActionScript程序,而渲染引擎则是把对象绘制在显示器上.

【指出容器的显示清单中有多少显示对象】
每个容器都有numChildren属性.

【把项目新增至显示清单】
addChild(child:DisplayObject)
addChildAt(child:DisplayObject, index:int)
index: 添加该子项的索引位置.如果指定当前占用的索引位置,则该位置以及所有更高位置上的子对象会在子级列表中上移一个位置.

【从显示清单中移除项目】
removeChild(child:DisplayObject)
removeChildAt(index:int)
index: 要删除的 DisplayObject 的子索引,该子项之上的任何显示对象的索引位置都减去1.
如果想移除窗口所有子元件,可以结合removeChildAt(),numChildren属性以及for循环.因为每次一个子元件被移除时,索引位置都会变化,所以,有两种方法可以处理所有子元件的移除:
1. 总是移除位置0的子元件;
2. 倒过来移除子元件,也就是从尾端开始.

【更改现有子项在显示对象容器中的位置】
setChildIndex(child:DisplayObject, index:int):void
可能用到的方法:
返回 DisplayObject 的 child 实例的索引位置: getChildIndex(child:DisplayObject):int
返回位于指定索引处的子显示对象实例: getChildAt(index:int):DisplayObject
注 意: 当子元件移到低于它现在所在位置的索引时,那么,从标的索引起,直到子元件索引前面的那个索引的所有子元件都会令其索引增加1,而该子元件就会指定至标的索引.当子元件移到较高索引时,从该子元件索引之上的那个索引起,直到标的索引的所有子元件都会令其索引往下减1,而该子元件就会指定至标的索引值.

【关于TextField以垂直方式把文字摆在按钮表面中心点的小技巧】
textField.y = (_height - textField.textHeight) / 2;
textField.y -= 2; //减2个像素以调整偏移量

【外部.swf影片载入和互动】
1. 监听init事件;
2. 透过content属性存取所载入的影片.
当所载入的影片做好足够的初始化工作,使其方法和属性可以接受互动时,init事件就会被发起.只有在载入器发起init事件后,才能控制影片.所载入的影片还没初始化就试着与它互动,是会产生执行期间错误的.
_loader.contentLoaderInfo.addEventListener(Event.INIT, handleInit); //当载入的.swf的属性和方法可用时
_loader.load(new URLRequest("ExternalMovie.swf"));
private function handleInit(event:Event):void {
var movie:* = _loader.content;
trace(movie.getColor());
movie.setColor(0xFF0000);
}

【TextField有两种类型:动态(dynamic)和输入(input),默认值为动态.改变TextField类型方法】
field.type = TextFieldType.INPUT; //selectable属性默认值为true
flash.text.TextFieldType.INPUT和flash.text.TextFieldType.DYNAMIC

【过滤文字输入】
TextField.restrict = "此处为可输入的内容";
field.restrict = "^此处为禁止输入的内容";
restrict属性支持一些类似正则表达式的样式:
field.restrict = "a-zA-z"; //只允许大小字母
field.restrict = "a-zA-z "; //只允许字母和空格
field.restrict = "0-9"; //只允许数字
field.restrict = "^abcdefg"; //除了小写字母abcdefg不允许外,其它都允许
field.restrict = "^a-z"; //所有小写字母都不允许,但是,其它内容都允许,包括大写字母
field.restrict = "0-9^5"; //只允许数字,但5例外
让restrict字符包含具有特殊意义的字母(例如-和^):
field.restrict = "0-9\\-"; //允许数字和破折号
field.restrict = "0-9\\^"; //允许数字和^
field.restrict = "0-9\\\\"; //允许数字和反斜杠
你也可以使用Unicode转义序列,指定允许的内容.例如:
field.restrict = "^\u001A";
注意:ActionScript有区分大小写的,如果restrict属性设为abc,允许字母的大写形式(A,B和C)输入时会变成小写对待形式(a,b和c),反之亦然.restrict属性只影响用户可以输入的内容,脚本可将任何文本放入文本字段中.

【设定输入框的最大长度】
TextField.maxChars:int

【向TextField追加内容】
TextField.appendText(text:String):void
与通过对 text 属性使用加法赋值来连接两个字符串(例如 field.text += moreText)相比,此方法的效率更高.

【显示HTML格式的文字】
TextField.htmlText = "<b>Html text</b>";
支 持的HTML标签集有: <b>,<i>,<u>,<font>(有face,size以及color属性),< p>,<br>,<a>,<li>,<img>以及<textformat>(有 leftmargin,rightmargin,blockindent,indent,leading以及tabstops属性,相应于 TextFormat类的同名属性)

【缩减空白】
TextField.condenseWhite = true;
删除具有HTML文本的文本字段中的额外空白(空格,换行符等),如同多数HTML浏览器所做的那样.
注意: 在设置 htmlText 属性之前设置 condenseWhite 属性

【自动大小调整和对齐】
TextField.autoSize = TextFieldAutoSize.LEFT;
可选之值:
flash.text.TextFieldAutoSize.CENTER
flash.text.TextFieldAutoSize.LEFT
flash.text.TextFieldAutoSize.NONE
flash.text.TextFieldAutoSize.RIGHT

【指示文本字段是否自动换行】
TextField.wordWrap = true; //自动换行

【用程序手段滚动文字】
水平方向以像素为单位,而垂直方向以行做单位:
scrollV: 指出文字框可见区域的最顶行,可读写;
bottomScrollV: 指出文字框内最底端可见行,只读;
maxScrollV: scrollV的最大值,只读;
numLines: 定义多行文本字段中的文本行数,只读;
TextField.scrollV = field.maxScrollV; //滚动到最后一页

【响应滚动事件】
field.addEventListener(Event.SCROLL, onTextScroll);

【样式化文字的方法】
1. 使用HTML标签进行样式化;
2. 使用TextFormat对象;
3. 使用CSS.
例如: HTML是用<font>标签,TextFormat对象是设定font属性,而CSS是使用font-family属性的.
受支持的层叠样式表(CSS)属性和值,及其相应的ActionScript属性名称(小括号内):
color(color),display(display),font-family(fontFamily),font-size(fontSize),font-style(fontStyle),font-weight(fontWeight),kerning(kerning),leading(leading),letter-spacing(letterSpacing),margin-left(marginLeft),margin-right(marginRight),text-align(textAlign),text-decoration(textDecoration),text-indent(textIndent)
受支持的HTML实体: <(小于号: <), >(大于号: >), &(和: &), "(双引号: "), '(撇号,单引号: ')
其中样式对象的两种写法:
写法一:
var sampleStyle:Object = new Object();
sampleStyle.color = "#FFFFFF";
sampleStyle.textAlign = "center";
css.setStyle(".sample", sampleStyle);
写法二:
var sampleStyle:Object = {color: "#FFFFFF", textAlign: "center"};
css.setStyle(".sample", sampleStyle);

【对用户输入的文字进行样式化】
使用defaultTextFormat属性,样式会施加至用户键入输入框的文字身上:
var formatter:TextFormat = new TextFormat();
formatter.color = 0x0000FF; //把文字变成蓝色
field.defaultTextFormat = formatter;

【对现有文字的一部分进行样式化】
TextFormat.setTextFormat(format:TextFormat, beginIndex:int = -1, endIndex:int = -1):void

【设定文字框的字体】
例子:
HTML: field.htmlText = "<font face='Arial'>Formatted text</font>";
TextFormat: formatter.font = "Arial";
CSS: P{ font-family: Arial; }
也可以使用以逗号隔开的字体清单: formatter.font = "Arial, Verdana, Helvetica";
注意:
字体和字体群组不同.字体群组有三种: _sans,_serif以及_typewriter.
_sans群组一般就是指Arial或Helvetica这种字体;
_serif群组一般就是指Times或Times New Roman这种字体;
_typewriter群组一般就是指Courier或Courier New这种字体.

【嵌入字体】
使用[Embed]后设标签.[Embed]后设标签应该出现在ActionScript文件中,处于类宣告之外.你可以内嵌TrueType字体或系统字体.内嵌TrueType字体时的语法:
[Embed(source="pathToTtfFile", fontName="FontName", mimeType="application/x-font-truetype")]
pathToTtfFile: ttf文件的路径,TrueType字体的路径可以是相对的,也可以是绝对的;
FontName: 字体名称;
内嵌系统字体的语法:
[Embed(systemFont="Times New Roman", fontName="Times New Roman", mimeType="application/x-font-truetype")]
fontName: 以相同名称作为实际系统字体名称.
注 意: 在使用嵌入字体时,要把TextField的embedFonts属性设为true,这样TextField只能用内嵌字体了.如果你试着替 embedFonts设为true的TextField使用设备字体,什么都不会显示.如果embedFonts设为true,就无法指定以逗号相隔的字体清单.

【建立可以旋转的文字】
使用内嵌字体.当你旋转文字框时,设备字体就会消失.

【显示Unicode文字】
1. 从外部来源载入Unicode文字;
2. 假如你的编辑器支持Unicode(如 Flex Builder),则可以直接在ActionScript程序中使用该字符;
3. 使用Unicode转义字符,ActionScript里所有Unicode转义字符都以\u开头,后面再跟四位十六进制数字.
注意: 如果你想取得Unicode字符,在Windows下使用: 开始>所有程序>附件>系统工具>字符映射表.

【把Flash Player的焦点带给文字框】
stage.focus = field;
把焦点移除:
stage.focus = null;
注意: 当.swf文件首次载入至网页浏览器时,并没有焦点.因此,以程序的方式把焦点指定给Flash应用程序的一个元素前,必须先把焦点移至Flash Player.

【以ActionScript选取文字】
使用TextField.setSelection(beginIndex:int, endIndex:int):void
为了可以正常选取文字,文字框必须具有焦点:
stage.focus = field; //把焦点设给文字框
field.text = "This is example text"; //设定文字
field.setSelection(0, 4); //把"This"这个单词以高亮显示
使用只读的selectionBeginIndex和selectionEndIndex属性访问所选取的字符范围的索引.

【在文字内设定安插点(游标位置)并访问游标位置的索引值】
可以使用TextField.setSelection()把起始和结尾的索引参数都设成相同值,在文字内设定游标位置(假设具有焦点):
field.setSelection(0, 0); //在第一个字符前摆放安插点
trace(field.caretIndex); //输出游标位置的索引值

【当文本字段受到选取或取消选取时给予响应】
获得焦点时: FocusEvent.FOCUS_IN
失去焦点时: FocusEvent.FOCUS_OUT
通过键盘(Tab键)把焦点移除时: FocusEvent.KEY_FOCUS_CHANGE
通过鼠标把焦点移除时: FocusEvent.MOUSE_FOCUS_CHANGE
FocusEvent 类有一个relatedObject属性.就FOCUS_IN事件而言,relatedObject属性是刚才拥有焦点的对象的引用地址;对于 FOCUS_OUT,KEY_FOCUS_CHANGE以及MOUSE_FOCUS_CHANGE事件,relatedObject属性是刚接收到焦点的对象的引用地址.
FOCUS_IN和FOCUS_OUT事件都是在焦点改变后发生的,所以两者都是不可取消的事件.对于KEY_FOCUS_CHANGE和MOUSE_FOCUS_CHANGE事件,可以使用FocusEvent.preventDefault()方法取消默认行为:
field.addEventListener(FocusEvent.KEY_FOCUS_CHANGE, onKeyFocus);
private function onKeyFocus(event:FocusEvent):void {
if(field.text == "") {
event.preventDefault(); //当field没有任何文字前,不允许使用Tab键把焦点移除
}
//event.relatedObject就是刚才拥有焦点的对象的引用地址,即下一个获得焦点的对象的引用地址
}

查看文章

   

人人renrenAPI开发简易指南

2009年11月04日 星期三下午 01:48

是时候研究一下国内的开放式API了,所以抽时间搞了一下,先从校内下手吧,相对来讲他的资料算是最多的了。但是即使如此,想从零开始写一个应用出来,还真是花了我不少功夫。资料实在是太难找了。校内的API从6、7月份就出来了,还弄了个专门的Wiki作为开放平台的门户,但是里面的资料出奇的少,除了对几个api函数的说明,对xnml的简单说明,其它的几乎为0。所谓的一个上手指南只讲了怎么注册用户和怎么注册程序,注册完以后的开放过程却一点也没提。想根据这份东西写个真正的应用出来,简直是不可能的任务。没办法,上Google,上社区,上应用的论坛,一篇篇帖子里找线索,最后总算是把一个应用给凑出来了。

如此糟糕的技术支持能力,直接决定了校内API应用的未来。

开发过程简介:

首先需要注册成校内用户,然后在自己的菜单上有个应用,添加一个“开发者”应用,这里面包括一个社区,一些开发所需要的链接。进入这个应用以后,可以看到一个申请开发许可证的按钮,点击就进入设置应用属性的环节,起名字,定URL之类的。(这一步在校内的Wiki上是有说明的。)有个安装到校内的选项,默认是否,结果选了以后我的应用就变成了外部应用,在校内只提供一个链接进入而已,这当然不行了。当我把应用删了重新添加的时候,原来使用的那个URL被占用了,无耐,换了个更难看的URL。应用还有一个重要的属性,就是运行状态,是以iframe形式还是xnml形式,这个待会再讲。第一次建议先选iframe形式,这个是随时可以修改的。

这些东西都设置完,应用就生成了。你会得到一个api_key,一个secret key,不过这两个东西都没什么用。

校内应用的工作原理:

如果是xnml方式的应用,用户访问apps.xiaonei.com/xxxxx/yyyyy这样一个地址的时候,xxxxx代表你申请一个应用的时候自己定义的那个URL,校内的API服务器会在后台将用户对该页面的请求(包括所有参数)转发给你的应用,也就是你申请应用的时候填的那个自己的应用地址。如果你的应用在你的服务器上是www.aaa.com/xxxxx/这样一个目录,那么上面这个请求就会被转发到www.aaa.com/xxxxx/yyyyy这里,不管yyyyy是个html页面还是个目录形式。转发的同时,还会多几个参数过来,包括当前用户的id,当前用户的sessionid,还有你的api key。你后续的所有的页面的链接,都要写成以apps.xiaonei.com开头的地址,由它来转发请求。

如果是iframe的应用就简单多了,海内直接生成一个iframe,把你注册时填的那个起始地址放进去,同时包括前面说的几个相同的参数。剩下的事情他们就不管了。

因为每次请求都是校内的服务器发给你,所以你的服务器上写Cookie或者session之类的东西是没有用的,必须每次取得这几个参数来决定当前用户是哪一个。(校内在这里有一个极其严重的设计失误,那就是没有用到创建程序时生成的那个secret key。校内发过来的这三个参数只能帮你确定是哪一个userid发过来的请求,而这三个参数之间是没有什么关联性的,比如你无法根据sessionid来判断这个userid是否合法。而在iframe状态的应用里,这三个参数直接暴露在浏览器代码里,用户只要复制下来,把userid改成另外一个数字放到浏览器地址栏里就OK了。现在,如果你想确保访问用户的合法性,就必须要通过校内的API调用,到他的服务器上去,把这三个参数发过去,看它的返回结果,多一次网络调用所带来的时间损失,远远大于任何的数据库运算或者数字运算。实际上,校内只要加上第四个参数,也就是你的secret key和其中任何一个参数合并后的md5码,你在取值以后用同样的算法生成md5码,比较一下跟传过来的值是否相等就OK了,完全不需要为了验证用户合法性而增加一次网络调用。更可恶的是,每个页面你都要做一次这样的网络调用。当然,你也可以在验证合法以后用自己的服务器保存一下userid和sessionid的对应关系,下次请求如果仍然是这两个数值就不用再网络验证了,但是这又增加了无谓的数据库调用。)

你已经拿到了用户在校内上的用户ID,并且确认他已经成功登录校内,接下来就是处理你自己的业务逻辑。比如在你的数据库里新增加一个用户,并绑定到这个校内ID上,然后对该用户进行某些操作。最后就是返回页面内容。

这里就到了iframe和xnml模式的区别。如果是iframe模式,你返回的页面内容直接显示在iframe里,那自由度就大多了,跟普通的网页一样,想怎么做就怎么做。不过要小心iframe跨域的js问题。

如果是xnml模式,你返回的内容(还是普通的html,但是没有body标签了)是由校内的api服务器接收到的,他们对内容进行解析,然后显示在自己的层里,展现给用户。为了防止一些非法操作,xnml规定了哪些html语法是合法的,如果出现不合法的语法,会直接报错。(这里又缺少一个可用的debug方式,一旦在这个步骤出现页面错误,极难调试。)Wiki的文档里写了这里是不允许出现自己的css语法的,但是实际上现在又是可以用css的,至少style和class两个关键字都是允许的。除了普通的html语法,xnml还定义了一些他自己的语法,通过这些语法,你可以在页面上直接显示出用户的姓名头像链接好友等等信息,而无需在你的程序里通过API调用去获取。

如果你要使用form来post数据,把form的action定义成相对路径,相对于你的这个应用的实际路径,比如,如果你的原始action应该是www.aaa.com/xxxxx/save.jsp,那么只要写action=’save.jsp’就可以了,在显示出来的时候,校内会将它替换成他们自己的相对路径,然后转发到正确的地址。

最后说说最有技术味道的东西,对校内API的调用。

现在校内一共只公开了为数不多的几个API,可以获取用户信息,好友信息,给用户发通知,现在还可以增加用户的新鲜事。对这些API的用户方式都是通过Post来实现的,Post的地址是固定的,就是这个地址:http://api.xiaonei.com/restserver.do,你需要对这个地址进行Post,发送几个参数过去,包括api_key,session_key,也就是校内传过来的那两个值,还有method,就是你要调用的方法名,然后不同的方法需要使用不同的参数,这些就可以去看校内的API文档了。这些参数Post过去以后,校内会返回一个xml,(虽然所有的调用都有个response格式的参数,可以选择xml还是json,但是,即使你选了json,它还是返回xml。)xml里要么包含错误码,要么,包含了你需要得到的信息,自己解析一下就行了。

所有的调用过程,包括你返回的参数和传递的参数,还有校内给你的参数,全部是utf8格式的,包括你生成的html。

这里只是一个开发过程的简单描述,不涉及代码,有兴趣的可以去看看校内自己的示例代码,是java的。有必要的话我也可以用代码的方式来写个demo,看大家的需要了。(论坛上面的hello world的demo对于实际开发的帮助几乎为0)。

本文来自:http://www.unfish.net/archives/331-20080910.html

下面是有关校内开放平台的介绍 校内网大家都知道吧,最近校内网推出了应用程序开发接口供校内网用户来开发应用程序扩展,今天我们来介绍下校内网开发的标识语言XNML,利用它我们就可以为校内网开发自己想要的应用程序了。 什么是XNML XNML是校内网为校内网用户提供的一种标识语言,使用它我们可以调用校内网的指定数据,利用这些数据可以开发我们需要的应用程序。 XNML编写程序的原理是什么我们先分析一下从一个用户发出浏览网页请求到呈现网页内容的这个过程: 1、校内网用户访问你用XNML写的网页,此时会对校内网的服务器发送请求。 2、校内网的应用程序(app)服务器接收用户请求,并根据该应用程序的相关配置找到编程者存放应用程序的另一台服务器(我们的XNML代码就放在这台服务器上) 3、读取编程者编写的网页程序,把其中的XNML标签翻译转换成相应的表现形式(这个过程不需要我们了解,校内网也不会公开) 4、转换过后,结果就会呈现在刚才发出请求的用户面前。我们所写的代码被校内网的服务器读取并翻译,最后呈现出来。翻译的内容就是我们在程序中所用到的XNML。XNML就充当着这样的角色:临时变量。 该怎么看待XNML 谈谈个人的理解,XNML就像校内网提供的一个中间接口,我们不用直接访问校内网的数据库,直接利用这个接口,就可以得到我们需要的数据。比如我们需要得到ID为12345这个校内网用户的姓名和这个用户所在的网络,怎么得到呢,我们只需要在自己的网页程序(HTML形式)中,写入 就可以了,上面的这个XNML片段在校内网中被调用的时候就会自动被校内网服务器解释成如下字符串: 张三(XXXX大学) 这个用户的姓名及所在网络的字符串,也就是说,在显示的时候,他会以该编号用户的姓名和所在网络替换咱们写的这句代码。 简单的XNML例子(Hello,World) ASP PHP echo 'Hello,'; ?> ASP.Net Response.Write("Hello,"); 比如我在校内网的名字叫张三,当我访问这个网页是,就会显示 Hello,张三 上面的例子很简单,但是很能说明问题,具体的细节问题大家请访问http://dev.xiaonei.com来看,把XNML嵌入到你的动态网页中,就可以制作出你想要的应用程序了。数据放在那,关键就看你怎么用了。 从头开始,我们来做一个校内网应用程序 如果你从来没有接触过校内网应用程序这个概念,那就太落伍了(开玩笑哈),没关系,现在从头开始! 1、我们先要安装一个“开发者”应用,这是我们通向自己开发的毕竟之路(要是我的应用程序有这个待遇就好了,hoho),安装地址:http://app.xiaonei.com/developers/home.do(当然得先登录校内网,再访问喽) 2、安装完毕后,你会在左侧的列表中看到可爱的它,点击它。在右上角你会看到“申请开发许可证”按钮,点击进入。 3、这时就改配置你的应用程序了(什么?没想好做什么,那就呆一边想吧),下面只说明几点比较重要的。 Callback URL:你编写的网页程序存放的URL路径,比如(http://www.dzstu.com/xxxx),我们的网页程序全都放在你的服务器上的这个xxxx路径里 Canvas Page URL:后面的文本框给你的应用起个英文名字填里面(必须超过6字符),假设我们这里填写dzstudotcom,下面选择"使用XNML" 应用的服务器IP地址:填写你的网页程序存放的服务器的IP地址,不知道?ping下先,什么?ping不通,问客服!无奈中.... 安装后跳转地址:http://apps.xiaonei.com/dzstudotcom/index.php (一般应该是你程序的首页,不过你要是比较另类那就随便了,但前面必须是那个形式哦) 默认XNML:这个是显示在安装了这个应用程序的个人主页里的,有需要的话可以写写。 左侧导航地址:写上你应用程序的首页吧,比如这里的http://apps.xiaonei.com/dzstudotcom/index.php ,到时候会以这个地址出现在左侧的导航菜单里,然后保存。 4、写你的程序吧,还呆着想啥 5、填写应用程序说明,补充图片封面什么的,然后拿你的Canvas Page URL发给别人安装吧,安装5个人就可以提交审核了,审核通过的话,那么恭喜你,你的服务器要经受考验了。

查看文章

   

Manyou API开发感受

2009年11月04日 星期三 下午 02:03

做完了校内的API版本以后,本想做海内和开心网的,找半天没有一点关于API的消息,似乎从来没有公布过一样。但是里面的那些应用又不像全部是公司开发的,难道属于内测阶段?

于是转去研究UCenter的API-Manyou。初看起来,Manyou的API完成度更高,文档也更细,而且已经有了MYQL和MYJS,比校内的更加成熟。结果,真正开发起来,才发现简直是场恶梦。

注册新程序的流程跟校内一样,但是少一个映射URL的选项,也就是说你的程序没有短路径。

API的函数和参数的说明都不少,但是偏偏没有如何调用。(有,但是是PHP版的,而且是PHP开发包的调用方法,如果你想自己做Post请求,Sorry,即找不到服务器地址,也找不到接收到的参数的说明。)

Python已经有了一个开发包,结果装上以后却说有一个函数未定义,启动不起来。

尝试了N多种方法,都没有办法成功的发送一个Post。

然后放弃了这种方法,只接收用户ID,不打算进行验证了。界面终于显示出来了。又发现其它页面的相对链接都不对了。又是一阵调试加猜测,总算找对了方法,把链接都改成相对于你的目录的链接,但是又不是相对链接,而是写绝对链接。

最后,看起来所有的页面都显示正确了,但是一个Form的Post又遇到了困难。我没办法让这个Form往正确的地址Post。换了多种方法,始终提示Bad Request。而且,Form里面被插入的隐藏变量居然跟Get的时候不一样,没有my_sig_uid字段……

算了,放弃了。浪费我一天的时间。

Tags: API开发, Manyou

This entry was posted on 星期一, 九月 15th, 2008 at 15:56 and is filed under 技术文章. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

5 comments so far

freeman

1

从您的反馈来看我们的文档确实要完善的还很多。呵呵,还是很希望您能加入到我们的开发者行列来的 :) my的平台和别的有些不同的地方,几个问题我说明一下:

1. 路径的问题,为了和站长共赢 应用的pv是要和站点共享的,所以要显示成站点的,短路径也就没有什么用了。
2.api的文档主要面向使用接口的开发者的,但要开发自己客户端的话我们有专门的一篇介绍文档:
http://wiki.developer.manyou.com/wiki/index.php/如何开发Manyou_API客户端
3.python客户端是由网友提供的,可能还需要大家一块去完善,有什么具体的问题 可以希望能反馈到开发者论坛:
http://fourm.developer.manyou.com
4. bad request的问题 应该也是理解上的问题导致的,因为现在己经有几十个应用开发出来,并在正常使用了。

九月 16th, 2008 at 00:54

非鱼

2

对于第四条,这几十个应用,似乎全部都是Post到当前页面的,我找不到办法Post到另外一个页面上去。

九月 16th, 2008 at 09:00

非鱼

3

Manyou的审核过程居然会对程序的功能提出意见,要求我加上某个功能……这似乎有点过分了。

九月 23rd, 2008 at 09:31

匿名

4

Form里面被插入的隐藏变量居然跟Get的时候不一样
没有my_sig_uid

你读下COOKIES看。全在里面。所有的POST过来的数据由MANYOU.PHP生成COOKIES

要说明一下,POST是MYML用的,GET是IFREAM用的。

十二月 5th, 2008 at 21:29

非鱼

5

不要使用$_GET或者$_POST,直接使用$_REQUEST就行了。

查看文章

   

校内/Manyou/Alisoft API应用开发Demo

2009年11月04日 星期三下午 02:04

其实要写个完整的Demo是挺困难的,而且目前我只做了Python的开发,没有写过其它版本,而且以我的习惯,我也不喜欢写完整的代码给别人去抄,所谓授之以鱼不如授之以渔。写个自然语言的版本吧,写起来简单,看的人也容易使用自己喜欢的语言来搞定。

为什么把三个放在一起呢,其实它们的API区别不大,流程都是一样的,只是参数名字的区别而已。

API的工作流程如下:(这些东西三个网站的开发手册里都有)

用户登录到校内/Manyou/Alisoft以后,进入他的应用列表,可以看到他安装过的所有的应用,点击某个应用的时候,就会跳到一个特定的地址。校内和Manyou有XNML/MYML的开发方式,在这种方式下,用户的每次点击都是点到他们的地址上,在他们的服务器上把请求转发到你的网址。这种情况下你在自己的网站上是不能用Session或者Cookie来记住用户的,因为所有的用户都是同一个地方发来的请求。所以你只能每个页面都要从他们传过来的参数里获取当前用户的信息。而IFrame的方式要简单的多,只要给他们一个入口,他们就会生成一个IFrame把参数传入你这个入口地址,以后用户的所有操作都是在你的网站上,所以只要这个入口页面处理查询用户信息并用你自己的Cookie来登录,剩下的跟其它的页面逻辑是一样的。Alisoft也是这样做的。所以这里我只讲IFrame方式。

校内和Manyou是跳到它自己域名的一个URL,然后生成一个IFrame链接到你网站的一个地址,Alisoft则是直接跳到你的网站上的地址。跳到这个地址的时候会带一些参数过来,比如当前用户的ID,SessionID,还有其它一些参数,但是真正有用的就是这两个。凭这两个参数,你就可以反过来去查询该用户的所有信息。

所以你首先需要一个处理登录的页面,接收他传过来的参数,在参数里获取用户ID,SessionID,然后查询用户的真实身份和用户名,如果验证是从API应用里点过来的,就在你自己的站上查询这个用户ID是否已存在,如果存在就取出来设他的Cookie或Session让他登录,如果不存在,就生成一个新用户,跟这个用户ID绑定起来,然后让他登录就行了。用户再点你其它的链接,就是你网站的一般逻辑而已了。

各种语言都有自己发POST请求的方式,需要自己去看看帮助了。

查询用户信息的方式:

校内的:只需要在REQUEST里获取这两个参数:xn_sig_user,xn_sig_session_key,然后往这个地址http://api.xiaonei.com/restserver.do Post这些参数:

api_key:你的应用的Key,官方给出来的那个串,method:’xiaonei.users.getInfo’,session_key:就是前面获取的这个,call_id:0,sig:空字符串,v: ‘1.0’,fields:’name,sex’,uids:前面获取的那个user。

单引号括起来的就是固定字符串。至于sig,本来它应该是个用来验证请求身份是否合法的加密串,但是校内现在并没有用到,所以传个空的过去就行。如果用户是合法的,你就会得到一个包含<name>和<sex>的XML文本,剩下的应该是你自己的问题啦。

Manyou的:你需要获取三个参数:my_sig_uId,my_sig_sessionId,my_sig_prefix,前两个跟校内一样,最后一个是该用户实际所在站点的URL(因为Manyou是一个应用服务器给所有的UCenter子站服务的)。当然还有个参数my_sig_key可以用来验证传过来的参数是否合法,如果你只需要获取用户ID,不需要知道他的名字,就用这个参数来验证的话就可以省却一次POST的时间了。

然后需要需要往这个地址http://api.manyou.com/openapi.php POST这些参数:

api_key:你的应用的key,官方给的,format:’JSON’,(否则默认返回PHP格式的),method:’user.getinfo’,session_key:前面获取的sessionId,v:’0.1′,args[fields]: ‘name,sex’,args[uids]:前面获取的uId,sig:加密字符串。

重点在这个加密字符串的计算上,它的算法是把通用参数按字母排序,再加上你所调用的这个API方法的专用参数,再加上你的应用的安全码(申请的时候给的),拼成一个字符串算出来的MD5。比如上面这个方法,拼字符串就是:

‘api_key=’+apikey+’&format=JSON&method=user.getinfo&session_key=’+my_sig_sessionId+’&v=0.1&args[fields]=name,sex&args[uids]=’+userid+’&’+code

注意我中间引号外面的是自己的变量名,别照抄。最后的code就是你的安全码。对这个字符串算一个MD5就是前面需要POST的那个sig参数的值了。

这样如果请求合法,你会得到一个JSON格式的返回,格式为"name":"用户名","sex":"性别"。你只要分解字符串就可以拿到这个用户名了。剩下的就是自己的问题了。

Alisoft的:跟Manyou的非常相似

你需要获取三个参数:user_id,app_instance_id(就是sessionID),token(有特殊用途)。

然后往这个地址http://sipdev.alisoft.com/sip/rest (正式上线后把域名里的dev去掉)POST以下参数:

appId:你的应用的编号(官方给出的),appInstanceId:前面给出的,sip_apiname : ‘alisoft.validateUser’,sip_appkey:跟appId一样,sip_timestamp:当前时间字符串,格式为2008-10-01 08:00:00,token:前面获取的那个,userId:前面获取的那个,sip_sign:加密字符串。

加密字符串的计算方法跟Manyou类似,但是串联字符串的时候没有&和=,而是把所有的内容串在一起,而且你的安全码是放在字符串的最前面的,前面这个方法的字符串就是:

code+’appId’+appid+’appInstanceId’+instance+’sip_apinamealisoft.validateUser’+’sip_appkey’+appid+’sip_timestamp’+now +’token’+token+’userId’+userid

code是你的安全码,now就是前面说的时间字符串,其它的变量一看就知道了。

返回的内容只有一个<String>1</String>,包含这个就说明该用户是合法的,但是并不会返回他的用户名,如果你想获取用户名的话,还得再去调用另外一个API,自己去看看官方的文档吧(因为他的用户可能是淘宝的,也可能是阿里巴巴的)。调用方法是一样的。

查看文章

   

校内api教程

2009年11月04日 星期三下午 03:15

> 前言
> 本文档将以一个例子的形式进行讲解使用校内API的流程。
> 下文的介绍中假定你是一个ABC网站的拥有者,网站地址是www.abc.com。
> 文中 Application 表示一个应用,你的网站将被视为一个Application。
> Ok,我们开始吧。
> 约定
> 1、 你的Application必须要在xiaonei上事先进行申请登记,登记成功后Xiaonei为ABC提供一个API_KEY,作为一个唯一标识,字符串的形式。
> 2、 用户必须先到xiaonei进行登录。
> 3、 用户需要接受这个Application提供的相关服务,否则用户在ABC站点上查看相关校内网的数据信息s。
> 4、 ABC提供一个callback_url给xiaonei,此链接用于xiaonei验证用户成功后,回跳到ABC站点的url。
> 流程
> 1:登录xiaonei的URL
> http://login.xiaonei.com/L.do?api_key=YOUR_API_KEY&v=1.0
>
> ABC的网页应该提供登录到xiaonei的入口,入口链接为上面的。用户点此链接后,xiaonei的登录验证服务会判断用户是否已经登录到xiaonei。
> URL参数表
> api_key(必须的) xiaonei提供给ABC站点的
> v(必须的) 目前固定写 1.0
>
>
> 2:xiaonei回调ABC的callback_url
> Xiaonei验证用户已经登录校内,且用户已经接受了ABC站点提供的服务,则回调到ABC提供的callback_url地址。并将认证通过的加密串传给此链接。形式如下:
> http://www.abc.com/callback_url? auth_token=
>
> 上面参数auth_token的值是xiaonei生成并传入的。
> ABC需要接收此auth_token参数,并根据此auth_token进一步向xiaonei发送请求得到session_key。
> URL参数表
> auth_token(必须的)
>
> 3:得到校内用户的session_key
> http://api.xiaonei.com/restserver.do?method= xiaonei.auth.getSession &
> api_key=YOUR_API_KEY&v=1.0&auth_token=
>
> URL参数表
> Method 固定值:xiaonei.auth.getSession
> api_key(必须的) xiaonei提供给ABC
> v(必须的) 目前固定写 1.0
> auth_token 上一步获得的
>
> 成功返回值
> 成功后返回一段XML文本,例如XML文本:
> <?xml version="1.0" encoding="UTF-8"?>
> <auth_getSession_response>
>     <session_key>5f34e11bfb97c762e439e6a5-8055</session_key>
>     <uid>8055</uid>
>     <expires>1173309298</expires>
> </auth_getSession_response>
>
> ABC方面需要解析此XML文本,提取出session_key串,并将session_key存储起来以备后面使用;<uid>节点表示用户id。
> 失败返回值
> 失败后返回一段XML文本,例如XML文本:
> <?xml version="1.0" encoding="UTF-8"?>
> <error_response>
>   <error_code>5</error_code>
>   <error_msg>未经认证的IP地址(ip: 20.1.2.3)</error_msg>
> </error_response>
> <error_code>节点表示错误代码,可参照下面"错误代码对照表"。
>
>
>
>
> 4:从xiaonei取得一个用户信息的URL
> http://api.xiaonei.com/restserver.do?method= xiaonei.users.getInfo &
> api_key=YOUR_API_KEY&v=1.0&session_key=&uids=&format=
> 提交方式
> 使用POST提交。
> URL参数表
> method(必须的) 固定值:xiaonei.users.getInfo
> api_key(必须的) xiaonei提供
> v(必须的) 目前固定值:1.0
> session_key(必须的) 取自上一步生成的串
> uids 一个用户id,如:8055
> format(可选的) Response的格式。请指定为XML(缺省值),
>
> 成功返回值
> 成功后返回一段XML文本,例如XML文本:
> <?xml version="1.0" encoding="UTF-8"?>
> <users_getInfo_response>
> <user>
> <uid>8055</uid>
> <name>刘德华</name>
> <sex>1</sex>
> <birthday>1961-09-27</birthday>
> <hometown_location>
> <country>中国</country>
> <province>黑龙江</province>
> <city>哈尔滨</city>
> </hometown_location>
> </user>
> </users_getInfo_response>
>
> ABC需要解析此XML文本,提取出所需信息。<uid>节点表示用户id,<name>节点表示用户名字。
> <sex>节点表示性别,值1表示男性;值0表示女性。
> <birthday>表示出生时间,格式为:yyyy-mm-dd,ABC方面需要自行格式化日期显示格式。
> <hometown_location>节点表示家乡所在地,<country>节点表示国家,<province>节点表示省或州,<city>表示城市。
> 失败返回值
> 失败后返回一段XML文本,例如XML文本:
> <?xml version="1.0" encoding="UTF-8"?>
> <error_response>
>   <error_code>5</error_code>
>   <error_msg>未经认证的IP地址(ip: 20.1.2.3)</error_msg>
> </error_response>
> <error_code>节点表示错误代码,可参照下面"错误代码对照表"。
>
>
> 错误代码对照表
> 错误号 错误描述 适用的方法
> 11 一个未知的错误发生 (all)
> 12 服务临时不可用 (all)
> 13 未知的方法
> 14 应用已达到设定的请求上限 (all)
> 15 请求来自未经授权的IP地址 (all)
> 16 此方法必须运行在api.xiaonei.com (all)
> 100 无效参数 (all)
> 101 提交的api_key不属于任何已知的应用 (all)

查看文章

   

AS3动态获得类名及类的方法

2009年12月01日 星期二下午 05:33

1.获得某个实例对象的类名:getQualifiedClassName (实例名字符串表达式);
stage.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandle);
function mouseOverHandle(e:Event):void {
    trace("over");
//    返回instance**之类的
     trace(e.target.name);
//返回元件名
     trace(getQualifiedClassName(e.target));
}
2.获得某个实例对象的类:constructor
dynamic class A {}
trace(A.prototype.constructor);      // [class A]
trace(A.prototype.constructor == A); // true
var myA:A = new A();
trace(myA.constructor == A);         // true
3.根据类名获得类: getDefinitionByName(类名);
package {
    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.utils.getDefinitionByName;
    public class GetDefinitionByNameExample extends Sprite {
        private var bgColor:uint = 0xFFCC00;
        private var size:uint = 80;
        public function GetDefinitionByNameExample() {
var ClassReference:Class = getDefinitionByName("flash.display.Sprite") as Class;
var instance:Object = new ClassReference();
            instance.graphics.beginFill(bgColor);
            instance.graphics.drawRect(0, 0, size, size);
            instance.graphics.endFill();
            addChild(DisplayObject(instance));
        }
    }
}
4.用得到的类实例化对象:一般中间要用一个无类型变量传递类,进行实例化;如:
var i=0;
var c:*=getDefinitionByName(getQualifiedClassName ("MyClass"+i));
var myClass:*=new c();

 

查看文章

   

AS3教程:写AS3十个注意

2009年12月01日 星期二下午 05:33

AS3教程:写AS3十个注意

总结起来需要注意的原则就是:尽量在编译的阶段发现错误,因为这时发现并解决错误远远要比在运行时出错解决起来容易的多。可是实际情况中很多人经常会违反这一原则,下面是我列举的10个技巧:

(1) 永远不要使用'Object' 来存储数据. 因为这是一种绕开编译器检查的做法,完全不符合面向对象的思想。如果要用Hashmap或者相应的数组,那么可以用Dictionary。否则,请自已定义一个类,而不要使用Object来作为数据的存储器。

(2) 不要用Object来作为对象的类型。这是欺骗编译器的方法。如果必须这样用,最好在存取属性或者调用函数时,先进行强制性的类型转换,至少这是给编译器的一个提示,也帮助其他人理解你的代码。

(3) 也不要用*类型。

4) 不要将ActionScript的类声明为动态。

(5) 注意Application.application (和其他的无类型的框架属性). 这个属性有一些古怪,他应该是Applicaton类型的,因为他指向的实例必须是Application的子类. 但实际上他的类型是'Object', 无法应用编译时的检查。如果你一定要用,最好也进行类型的强制性转换。:

MyApplication( Application.application ).functionCall();

(6) 封装你的Xml。使用Xml与Server进行数据的交互非常方便,但是尽量避免使用Xml作为核心数据模型。从服务器收到数据后,尽量把Xml转换为强类型的对象模型。在Flex应用内部使用Xml是绕开编译器的作法。

(7) 不要使用DynamicEvent.

(8) 不要使用mx:Model。如上所述,请尽量使用自定义的强类型的类.

(9) 不要使用Cairngorm中的data属性,而应该继承扩展CairngormEvent来传递数据。

(10) 不要把编译器的严格模式关掉

查看文章

   

as3中字符串的处理

2009年12月23日 星期三下午 02:05

as3中字符串的处理

1.length
2.charAt ,charCodeAt
3.比较字符串
4.toString
5.+ concat
6. toLowerCase() or toUpperCase()
7. 字符串查找
8 隔离字符串
9 查找,替换,匹配字符串。
length 属性 每个字符串都有 length 属性,其值等于字符串中的字符数:
var str:String = "Adobe";
trace(str.length);
使用 charAt() 方法和 charCodeAt() 方法检查字符串各个位置上的字符:
var str:String = "hello world!";
for (var:i = 0; i < str.length; i++)
{
    trace(str.charAt(i), "-", str.charCodeAt(i));
}
比较字符串   <、<=、!=、==、=> 和 >。
获取其它对象的字符串表示形式,以toString() 方法来实现此目的。
var n:Number = 99.47;
var str:String = n.toString();
    // str == "99.47"
字符串连接的含义是:将两个字符串按顺序合并为一个字符串。
用 + 运算符来连接两个字符串
和 concat() 方法
在大小写之间转换字符串
toLowerCase() 方法和 toUpperCase() 方法分别将字符串中的英文字母字符转换为小写和大写:
substr() 和 substring() 返回字符串的一个子字符串。
在这两个方法中,第一个参数是给定字符串中起始字符的位置。
在 substr() 方法中,第二个参数是要返回的子字符串的"长度",
在 substring() 方法中,第二个参数是子字符串的"结尾"处字符的位置(该字符不包含在返回的字符串中)。
如:
var str:String = "Hello from Paris, Texas!!!";
trace(str.substr(11,15)); // 输出:Paris, Texas!!!
trace(str.substring(11,15)); // 输出:Pari
slice() 方法的功能类似于 substring() 方法。但可以使用负整数作为参数,
此时字符位置将从字符串末尾开始向前算起,

var str:String = "Hello from Paris, Texas!!!";
trace(str.slice(11,15)); // 输出:Pari
trace(str.slice(-3,-1)); // 输出:!!
trace(str.slice(-3,26)); // 输出:!!!
trace(str.slice(-3,str.length)); // 输出:!!!
trace(str.slice(-8,-3)); // 输出:Texas
查找匹配子字符串的字符位置
indexOf() 和 lastIndexOf()在字符串内查找匹配的子字符串,

var str:String = "The moon, the stars, the sea, the land";
trace(str.indexOf("the")); //输出:10
var str:String = "The moon, the stars, the sea, the land"
trace(str.indexOf("the", 11)); // 输出:21
lastIndexOf() 方法在字符串中查找子字符串的最后一个匹配项:
var str:String = "The moon, the stars, the sea, the land"
trace(str.lastIndexOf("the")); // 输出:30
如为 lastIndexOf() 方法提供了第二个参数,搜索将从字符串中的该索引位置反向(从右到左)进行:
var str:String = "The moon, the stars, the sea, the land"
trace(str.lastIndexOf("the", 29)); // 输出:21
创建由分隔符分隔的子字符串数组
split() 方法创建子字符串数组,该数组根据分隔符进行划分。

var queryStr:String = "first=joe&last=cheng&title=manager&StartDate=3/6/65";
var params:Array = queryStr.split("&", 2); // params == ["first=joe","last=cheng"]
split() 方法的第二个参数是可选参数,该参数定义所返回数组的最大大小。
另 split还支持正则表达式作为分隔符处理,这里不涉及正则处理
在字符串中查找模式并替换子字符串
match() 和 search() 方法可查找与模式相匹配的子字符串。
replace() 方法可查找与模式相匹配的子字符串并使用指定子字符串替换它们。
search() 方法返回与给定模式相匹配的第一个子字符串的索引位置。

var str:String = "The more the merrier.";
trace(str.search("the")); // 输出:9
对于search,match,replace都支持正则表达式匹配处理。

posted @ 2016-04-18 13:54  ouhy  阅读(1120)  评论(0编辑  收藏  举报