搜索
查看: 16680|回复: 24

[web] aardio网站开发、FastCGI开发入门教程

[复制链接]

185

主题

2541

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13973
发表于 2016-3-10 14:23:01 | 显示全部楼层 |阅读模式
aardio用户接触web开发的相对比较多,在aardio中开发桌面软件,应用web技术,HTML等等非常普遍,
所以大家切换到网站开发应当是轻车熟路,不会有太大的难度,现在很多软件应用都是基于服务端接口,几乎每一个软件都要与服务端接口互动,不仅仅是桌面软件,例如一些手机应用,客户端是HTML5,服务端是REST接口,这种模式是未来的方向,所以应用领域还是比较广的。

实际上在aardio中开发网站应用非常简单,大家可以把网站理解为控制台程序,
只不过取代io.print 的是 response.write 函数。一句aardio代码
response.write("hello")

就输出一个最简单的网页了。aardio直接支持与PHP类似的语言级模板语法,可以html,aardio代码混合生成页面,非常方便。

本教程基于 aardio v10  以上版本。

相关帖子

回复

使用道具 举报

185

主题

2541

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13973
 楼主| 发表于 2016-3-10 14:49:48 | 显示全部楼层

在aardio中创建“网站程序”工程

首先请在主菜单中点击新建工程:
new.jpg

在工程向导中点选【网站程序】,创建网站工程。默认的 main.aardio 中包含一个在本地启动 Web服务器的代码( 不需要安装IIS这些,直接用aardio实现的Web服务器)

创建一个Web服务器非常简单,几句代码就可以了,如下:
  1. import wsock.tcp.simpleHttpServer;
  2. var app = wsock.tcp.simpleHttpServer("127.0.0.1",8081);

  3. app.run(
  4.      
  5.     function(response,request){
  6.      
  7.     }
  8. );
复制代码
上面的代码在本地IP 127.0.0.1启动一个Web服务器,监听连接的端口为8081,
用户每一次连接都自动回调 函数  function(response,request){ }

每一个aardio创建的Web服务器应用都应该遵守相同的调用约定,使用相同的回调函数格式,并创建相同的response,request对象,无论是创建本地服务器,还是在IIS等Web服务器上创建FastCGI模块,网站应用程序的入口是一致的。


回复

使用道具 举报

185

主题

2541

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13973
 楼主| 发表于 2016-3-10 15:40:00 | 显示全部楼层

request对象(用于获取用户请求信息和提交的数据)

可以用下面的代码直接在网页上输出request对象的成员:
//让浏览器识别为JSON
response.contentType = "text/json"

//让aardio输出JSON时美化格式
response.jsonPrettyPrint = true

//输出request对象(aardio会自动将对象转换为JSON)
response.write( request )

request.environ

这是CGI环境变量组成的表对象,例如 request.environ.PATH_INFO,
实际上 request对象就是在 request.environ 的基础上的进一步封装,所以我们一般不直接使用 request.environ

request.method
HTTP请求方法,例如"GET"、"POST"

request.protocol
HTTP协议版本

request.scheme
请求的URL协议部分

request.host
请求域名,注意包含端口号,实际上就是HTTP请求头中的host字段。

request.serverPort
请求的服务器端口

request.url
请求完整URL,带主机名,不带GET参数

request.uri
请求路径,不含URL中的主机名以及协议部分,带GET参数,
这个值等于 request.path 加GET参数。

request.cookies
HTTP请求头中的cookies,这是一个表对象
可以这样 request.cookies["键名"] 获取ookie的值,

request.get
URL请求参数,也就是请求URL中问号后面的参数,也是一个表对象

request.post
提交表单参数,也是表对象

request.query("__")
这是一个函数,返回URL参数或表单参数,相当于在 request.get,request.post 中查找参数中指定的名字对应的值。

request.documentRoot
应用程序虚拟根目录的路径,相当于 io.fullpath("/"),也就是网站根目录

request.contentType
请求信息的MIME类型

request.contentLength
请求消息正文的长度

request.path
URL中的路径部分,注意请求路径不能开始于"/config/"或"/lib/",这两个目录禁止通过URL访问

request.sessionId
会话ID,应用程序需要自行管理会话过期时间,aardio仅提供一个会话ID,并存储于会话cookie中,该用数据的的时候应该用数据库。

request.createSessionId()
应用程序可调用此函数重新创建新的会话ID

request.postData()
获取原始上传数据,如果提交的是表单数据,当request.environ.HTTP_CONTENT_TYPE 为application/x-www-form-urlencoded时,原始上传数据会被解析为request.post对象, request.environ.HTTP_CONTENT_TYPE  为 multipart/form-data时上传的文件数据应使用postFileData函数读取。

request.postFileData()
request.environ.HTTP_CONTENT_TYPE  为 multipart/form-data时可以使用此函数获取上传的文件数据。
aardio在接收到文件上传数据时,会将其转存到临时目录( "/config/temp" 目录下 ) 并生成一个表对象,调用 request.postFileData()会返回该对象。例如上传文件中一个字段名是"file1",一个字段名是"username",那么获取上传文件数据的代码如下:
var fileData = request.postFileData()
if( fileData ){
    username = fileData.username.value();
//得到字段值
    fileData.file1.save("/upload.test.jpg");//保存文件
}

注意上传文件数据在请求结束后会被自动删除,应用程序应当自行决定是否保存,限制上传文件长度应当由Web服务器负责设定,解析上传文件格式使用标准库中的 fsys.multipartFormData,有兴趣可自行查看该模块源码。



回复

使用道具 举报

185

主题

2541

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13973
 楼主| 发表于 2016-3-10 15:53:06 | 显示全部楼层

response对象(用于响应请求并输出网页内容)

response.status
HTTP响应头中的状态码,字符串值,默认为 "200 OK"

response.contentType
HTTP响应头中的MIME文件类型,字符串值,默认为"text/html"

response.cookies
HTTP响应头中的cookies,表对象,例如:
response.cookies["名字"] = {
    value =
"值";
    expires = time().addday(7);
//过期时间
    maxAge = 3600; //过期秒数
}

response.cookieDomain
默认cookie域名,注意cookie域名不能为localhost(可以是本地IP),如果不设置默认值为 request.host,注意cookie域名不区分端口号

response.cookiePath
默认cookie目录,如果不设置默认值为 "/"

response.charset
输出字符集,可以为空,默认值为UTF-8,aardio10使用的默认字符集为UTF-8,不建议更改此值,更改此值需要自行对输出HTML转换编码。

response.headers
这是一个名值对组成的表对象,用于指定其他响应HTTP头。

response.jsonPrettyPrint
指定respose.write函数将对象转换为JSON输出时否缩进格式化。

response.write()
输出一个或多个值,参数将自动转换为字符串对象,可直接输出结构体,其他table对象转换为JSON输出。
需要注意调用此函数输出页面后(或HTML模板自动输出页面后),就会先输出HTTP头,输出HTTP响应头以后,再设置响应头有关的属性,例如 response.status 这些是不起作用的。

response.writeBuffer(缓冲区,长度)
response.write() 作用相同,不过输出的是缓冲区,注意缓冲区长度不应大于65535,response.write函数无此限制。

response.error()
输出一个或多个500错误信息,参数将自动转换为字符串对象,table转换为格式化的对象输出,注意500错误信息只有在Web服务器本地打开网页时才能看到,客户端默认是看不到详细错误信息的。

response.loadcode( aardio文件路径,其他调用参数 )
这个函数用于快速加载一个*.aardio模板文件并输出网页,所有参数都可以省略,默认加载的文件路径为 request.path,
其他调用参数在网页中可使用 var a,b,c = ... 语句在文件开始接收参数。


response.customErrors
这是一个表对象,键应当是一个HTTP错误代码(数值),值应当是一个回调函数,用于自定义response.loadcode函数的错误处理页内容,例如:
response.customErrors[404] = function(){
    response.status =
"404 Not Found";
    response.write(
"404 Not Found");
}

response.close()
关闭网页输出,这个函数并不需要我们自己调用,fastcgi模块会在请求结束后自动调用此函数。注意 respose.close并不会退出程序,应当使用 return 语句退出当前代码。

回复

使用道具 举报

185

主题

2541

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13973
 楼主| 发表于 2016-3-10 15:58:45 | 显示全部楼层

如何在网页上输出内容

有用户问到如何打开控制台输出错误信息,
实际上对于网站网页,网页输出你可以把他理解为一个“控制台窗口”,
在网页上输出信息的 response.write() 函数支持的数据类型比较多,类似于控制台中的 console.log() console.dump() 等函数,所以输出错误信息是非常方便的。

另外也可以用 response.error() 输出错误信息,response.error()输出的信息只能在服务器本地打开网页能看到,用户只能看到500错误页。

对于一个fastcgi应用,网页应用中的异常错误信息默认会显示为500错误,
如果是更底层的CGI错误,会调用 fsys.log输出错误信息到 cgi.exe 所在的 config目录下的日志文件中。
回复

使用道具 举报

185

主题

2541

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13973
 楼主| 发表于 2018-1-4 17:28:12 | 显示全部楼层

使用session对象

session 的使用非常简单,
直接用 session["键名"] 就可以存储键值了。

如果页面代码中使用session,那么session功能就会自动启动,
调用 session.start() 不是必须的。

可选调用 session.start() 函数来启动session,
这个函数的参数可以指定一个过期时间,以秒为单位,
默认为1800秒,注意过期时间将应用于当前网站下的所有session。

可选在 sessionHandler 名字空间下创建自定义的session加载器,
只要该加载器导入网站应用,服务端会优先使用自定义的加载器。

示例:
if(! session["count"] ){
    response.write(
"欢迎首次访问");
    session[
"count"]=1;
}
else {
    session[
"count"]=  session["count"] + 1;
    response.write(
"本次会话访问本站次数:",session["count"]);
}


回复

使用道具 举报

185

主题

2541

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13973
 楼主| 发表于 2016-3-10 16:24:30 | 显示全部楼层

WIN2008 上如何配置【FastCGI服务端】程序(更高版本系统大同小异)

首先在工程向导中创建一个【FastCGI服务端】程序,
改个合适的发布文件名,例如 aardio-cgi.exe,然后发布生成exe文件。

以 win2008 服务器为例,在远程桌面上右键点击【计算机】
2008.jpg

在右键菜单中点击【管理】,打开【服务器管理器】,
在角色中打开  【Web服务器 IIS】,如果没有该角色先右键点【角色】,并在弹出菜单点【添加角色】。

右键点【Web服务器 IIS】
2008-2.jpg
在弹出菜单中点【添加角色服务】,弹出角色服务窗口如下:
2008-3.jpg
在上面勾选【CGI】,然后点【下一步】,等待FastCGI模块安装完成。

打开【IIS管理器】,点选要设置的网站,选中【处理程序映射】
2008-4.jpg
双击上面的图标,打开处理程序映射窗口,在右边栏点击【添加模块映射】
2008-5.jpg
参数设置如上,模块一定要选"FastCgiModule",
如果你希望你的程序处理所有URL请求,可以把请求路径设为"*",这样所有图片等静态文件都会发到你的 cgi.exe,可能不必要的加重性能负担,一般不建议这么做。可以点击【请求限制】按钮,限制请求是否仅针对文件、或目录,如果你希望URL可以指向不存在的 aardio文件,应当取消请求限制。

最后点确定,FastCGI就安装好了,直接打开你的网站所在的目录,右键菜单中选择创建aardio工程就可以开始写网站了。
建议在网站的【默认文档】中添加 ‘main.aardio“的文件名,这样URL是一个目录时可以省略‘main.aardio“。

如果是64位系统,注意在【应用程序池】右面的【高级设置】中点选 “启用32位应用程序”并设置为True

回复

使用道具 举报

185

主题

2541

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13973
 楼主| 发表于 2016-3-10 16:38:22 | 显示全部楼层

WIN10 上配置FastCGI服务端

打开【控制面板/卸载或更改程序/启用或关闭Windows功能】

1、勾选 【Internet Infomation Servies / IIS管理控制台】
2、勾选 【万维网服务/常见HTTP功能】
3、勾选 【万维网服务/应用程序开发功能/CGI】

win10.jpg

打开IIS管理器
  1. import fsys.wow64;
  2. import process;
  3. fsys.wow64.disableRedirection(
  4.     function(){
  5.         process.execute( "C:\Windows\System32\inetsrv\InetMgr.exe" )
  6.     }
  7. )
复制代码


其他的设置跟前面的 win2008 是一样的。


回复

使用道具 举报

185

主题

2541

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13973
 楼主| 发表于 2016-3-10 17:20:15 | 显示全部楼层

常见问题解答

一、FastCGI服务端开发、部署常见问题
1、如果用新版aardio编写的代码,在旧版编译的CGI.EXE中运行报错,那么把旧版CGI.EXE重新编译一次就可以。

2、import导入的库,在一个进程中只会加载一次, 如果网站引用了修改的库,应当杀除CGI.EXE进程重启动,如果在服务器上编译CGI.EXE,此工程会在发布后自动执行此操作。工程内的发布前触发器,\.build\default.init.aardio 会在每次发布前停止已运行的CGI进程,这个操作需要管理权限如果在本机上安装IIS测试,本机测试建议以管理权限启动aardio开发环境

3、如果是64位系统,请在应用程序池属性中设置"启用32位的应用程序"为True

4、如果在开发中遇到任何错误,通过远程桌面登录后在服务器上本地直接打开网页,可以看到500错误的详细信息,CGI内部错误可请查看"CGI.EXE目录/config"下面生成的日志文件。

5、注意在编写网站时,有必要请输出日志文件来排查错误。



二、 在网站应用程序中为什么找不到 import 语句引用的库文件

有用户可能发现,怎么我写个网页,例如 import fsys;
然后就出错了,找不到 fsys 库模块了。

实际上你的网站程序并不是运行在aardio开发环境中,而是运行在 Web服务器中的。
所以你需要把引用到的库文件复制过去。

网站程序会在以下位置查找库模块文件,
首先在  cgi.exe所在目录下的 lib 目录下查找库文件,
找不到就到网站根目录下的 lib 目录下去查找库文件。
  
cgi.exe 下面库目录用 "~/lib/"表示,可以将标准库复制到这个目录下。
而网站根目录下的库目录在程序中用 "/lib" 表示,可以将工程中的用户库复制到这个目录下。

也可以在aardio工程中设置工程中的界面系统属性为"website",如下图:
website.jpg
然后在aardio中点击【发布】按钮,aardio会自动编译并发布网站,并自动扫描所有引用到的库文件输出到发布目录。这样发布后的 aardio文件是编译过的字节码,不能再以源码方式编辑。

三、如何重启 aardio-cgi.exe

注意在网站中你导入一个库以后,你下次再导入这个库时不会再重复加载。
即使一个用户的请求结束也一样,这也正是FastCGI与aardio的模块机制结合带来的优势,提供更好的性能,避免不必要的重复加载,但是如果你在这之后再修改库文件的话,就要注意先在进程管理器中结束aardio-cgi.exe。

可以写一段aardio代码自动结束cgi 进程,如下:
  1. //RUNAS//
  2. import ide;
  3. import process.file;
  4. process.file.terminate( "aardio-cgi.exe的完整路径" );
复制代码
如果在客户端,可以管理权限启动aardio,这样运行上面的代码就不会每次都弹出请求管理权限的确认对话框了。

注意你只要关闭aardio-cgi.exe的进程,不用考虑怎么启动aardio-cgi.exe,IIS会自动启动他。

回复

使用道具 举报

185

主题

2541

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13973
 楼主| 发表于 2016-3-10 17:25:36 | 显示全部楼层

aardio模板语法

在aardio代码中直接支持HTML模板语法。
一、一个aardio文件,即可以是纯aardio代码,也可以是纯HTML,也可以是HTML、aardio相互混合的模板代码,aardio都能自动识别并解析。

二、aardio源代码文件里可以直接书写HTML代码,在HTML代码中aardio代码必须置于 <? ..... ?> 内部,,类似PHP的模板语法, 但是要注意与PHP的区别是,aardio规定开始标记  <? 必须独立不能紧跟英文字母,例如 <?xml.....  不是合法的aardio代码段开始标记(aardio会认为这是一个XML标记)。 另外,aardio总是忽略?>后面或文件开始的空白字符(包含空格、制表符,换行)。

三、在一个aardio文件中如果混合了HTML代码,aardio将<? ..... ?> 之外的部分解析为: print("HTML代码") 以调用全局函数print输出HTML。

关于print函数的规则如下:
   1)、print允许接收多个参数,并且必须对每个参数调用tostring()转换为字符串
   2)、在一个aardio文件解析结束时,print函数将收到一个null参数调用
   3)、aardio允许print函数被重定义,但应当由负责模板输出来框架来定义,一般用户代码中不可修改print函数,并且print函数随时可以由框架重新定义并实际指向不同的函数(例如 web.layout 中每打开一次页面,print被重定向为向当前页面输出HTML)。

四、可以使用 <?=表达式?> 输出文本,该代码的作用类似于 print( 表达式 ) , 下面的写法也是允许的
<?
=
表达式
?>

五、aardio文件应当并且只能以UTF-8编码保存,不建议添加UTF8 BOM(如果添加了BOM,aardio仍然会自动移除)

六、aardio编辑器支持识别以上语法编辑HTML模板文件,可直接将HTML模板代码复制到aardio编辑器中运行并生成网页。

aardio开发环境也可以直接支持解析运行HTML模板,可新建一个aardio源码文全,复制下面的源代码粘帖到aardio编辑器中
<!doctype html>
<html><head><meta charset="utf-8"><title>帮助页面</title></head>
<body>当前时间<?
= time() ?>
</body></html>

然后点【运行】按钮,可以看到立即生成了一个网页。

回复

使用道具 举报

2

主题

12

帖子

611

积分

培训班

积分
611
发表于 2016-3-10 18:18:36 | 显示全部楼层

{:D}

回复

使用道具 举报

0

主题

5

帖子

260

积分

二级会员

Rank: 3Rank: 3

积分
260
QQ
发表于 2016-3-10 19:18:57 | 显示全部楼层

愈来愈强{:)}

愈来愈强
回复

使用道具 举报

1

主题

4

帖子

247

积分

二级会员

Rank: 3Rank: 3

积分
247
发表于 2016-3-10 21:17:12 | 显示全部楼层

aardio 越来越强大!期待更多的精品教程。

aardio 越来越强大!期待更多的精品教程。
回复

使用道具 举报

4

主题

19

帖子

418

积分

二级会员

Rank: 3Rank: 3

积分
418
发表于 2016-3-11 08:08:09 | 显示全部楼层

顶顶

顶顶
回复

使用道具 举报

0

主题

55

帖子

362

积分

二级会员

Rank: 3Rank: 3

积分
362
QQ
发表于 2016-3-11 11:03:01 | 显示全部楼层

好 {:victory:}

回复

使用道具 举报

0

主题

8

帖子

49

积分

培训班

积分
49
发表于 2016-4-7 20:29:06 | 显示全部楼层

强大,我是刚来学习的

强大,我是刚来学习的
回复

使用道具 举报

3

主题

19

帖子

147

积分

一级会员

Rank: 2

积分
147
发表于 2016-4-20 16:44:46 | 显示全部楼层

[i=s] 本帖最后由 justinwq 于 2016-4-20 16:46 编辑 [/i] 求助:如何取得ajax方式向后台提供的数据: 用的是easyu

本帖最后由 justinwq 于 2016-4-20 16:46 编辑

求助:如何取得ajax方式向后台提供的数据:
用的是easyui
1、from表单POST

  1.         <form id="ff" action="form.aardio" method="post">
  2.                 <table>
  3.                         <tr>
  4.                                 <td>Name:</td>
  5.                                 <td><input name="name" type="text" value="小王"></input></td>
  6.                         </tr>
  7.                         <tr>
  8.                                 <td>Email:</td>
  9.                                 <td><input name="age" type="text" value="28"></input></td>
  10.                         </tr>
  11.                         <tr>
  12.                                 <td></td>
  13.                                 <td><input type="submit" value="Submit"></input></td>
  14.                         </tr>
  15.                 </table>
  16.         </form>
复制代码


在后台.aardio文件中可以通过request.post["name"]或request.query("name")取得post过来的name值。

2、datagrid 采用的是ajax方式异步提交的参数

  1. <script type="text/javascript" >
  2. $(function () {

  3.         $('#dg').datagrid({   
  4.                 width:500,   
  5.                 height:150,
  6.                 url:'datagrid.aardio',
  7.                 title: 'My Panel',
  8.                 [color=DarkOrange]queryParams:{
  9.                         name:'张三',
  10.                         passw:'abcd.123'
  11.                         },[/color]
  12.                 columns:[[   
  13.                         {field:'id',title:'id',width:100},   
  14.                         {field:'分类号',title:'分类号',width:100},   
  15.                         {field:'分类名称',title:'分类名称',width:100,align:'right'}   
  16.                 ]]   
  17.         });
  18.        
  19. });       
  20. </script>

  21. <table id="dg"></table>  
复制代码


在后台.aardio文件中却不能通过request.post["name"]或request.query("name")取得post过来的name值。
通过response.write( request.postData() ) 输出的结果   name=%E5%BC%A0%E4%B8%89&passw=abcd.123   
有什么好的方式可以把name 和passw的值提取出来,而在php中用$_post['name']就可以取得了。
回复

使用道具 举报

30

主题

695

帖子

4178

积分

超级版主

Rank: 8Rank: 8

积分
4178
发表于 2016-4-20 19:50:33 | 显示全部楼层

[quote][size=2][url=forum.php?mod=redirect&goto=findpost&pid=71086&ptid=13210][c

justinwq 发表于 2016-4-20 16:44
求助:如何取得ajax方式向后台提供的数据:
用的是easyui
1、from表单POST

ajax提交的自定义数据可以自己解析,例如:
request.post = inet.url.splitParameters( request.postData() )

没有自动解析是因为你没有在参数中指定正确的格式。
例如jquery ajax 正确指定参数就可以解析出来
$.ajax({
    type: "post",
    dataType:
"html",  
    url:
"http://127.0.0.1/",   
    data:{
        name:
'张三',
        passw:
'abcd.123'
    },
    success:
function(msg){
        alert( msg );
    }
} );

回复

使用道具 举报

3

主题

19

帖子

147

积分

一级会员

Rank: 2

积分
147
发表于 2016-4-21 00:51:55 | 显示全部楼层

[quote][size=2][url=forum.php?mod=redirect&goto=findpost&pid=71088&ptid=13210][c

quicker 发表于 2016-4-20 19:50
ajax提交的自定义数据可以自己解析,例如:
request.post = inet.url.splitParameters( request.postDat ...

十分感谢,已通过inet.url.splitParameters( request.postData() ) 解析成功。
至于重新指定easyui datagrid提交参数的格式,我再研究一下。
回复

使用道具 举报

3

主题

19

帖子

147

积分

一级会员

Rank: 2

积分
147
发表于 2016-4-26 01:05:34 | 显示全部楼层

在用php做登录时,可以在服务器端设置session,以保存用户信息,其它网页可以调用。 设置: session_start(); $_SESSION

在用php做登录时,可以在服务器端设置session,以保存用户信息,其它网页可以调用。
设置:
        session_start();
        $_SESSION['admin'] = $manager;
调用:
        <?php echo $_SESSION['admin']?>

在用fastcgi时,是不是没有session这个概念啊。

可以将post过来的信息用一个不带var的全局变量来保存信息,而且其它页面也是可以读取变量,不知道这个思路对不对!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

手机版|未经许可严禁引用或转载本站文章|站长邮箱|aardio.com|aardio官方社区 ( 皖ICP备09012014号 )

GMT+8, 2018-10-18 22:51 , Processed in 0.109375 second(s), 35 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表