(有朋友问上述问题, 愿把结论分享给大家).
摘 要:
服务器端脚本运行时, 它只会解释执行<% %>或<?php ?%> 之间的脚本语句, 它会把客户端脚本视作
普通文本. 而客户端脚本运行时, 服务器端脚本又是不可见的(客户浏览器上只有服务器端脚本的执行结果).
所以, 服务器端脚本和客户端脚本不能相互直接操作, 也不能相互直接调用.
客户端脚本与服务器脚本交换数据只能通过 GET和 POST 方法(即: URL?查询 和 post 方法)相互传递数据,
客户端脚本还可以通过Ajax, 先异步通信请求服务器动态获取查询结果, 然后再分析查询/输出结果 ..
要解决这个问题, 先必须弄清三个概念 :
a. 客户端脚本
b. 服务端脚本
c. B/S 模式中 " 客户端脚本" 与 "服务端脚本" 的通信原理.
1. 客户端脚本
客户端脚本主指运行在客户浏览器(Browser)端的脚本程序, 如 Javascript, VbScript,
通常将它们通过<script></script>嵌入在 html 源程序中, 由浏览器解释执行 ..
2. 服务器端脚本
服务器端脚本主指运行在服务器端(Server)的脚本程序, 如 perl, php, csp, asp(vbscript, javascript),
它们通常通过<% %>或<?php ?>等嵌入在 html 源程序中或直接运行输出html文件,
这些脚本程序由服务器的脚本解释器( 或编译器)解释(或编译)执行.
3. 区别/联系
客户端的解释器是由浏览器提供, 不必另外安装. 服务器端脚本解释(编译器)由脚本开发商提供,
一般需要另外安装和配置(perl, php, csp, asp等的开发/运行环境).
另外, 在 ASP 中虽然 VbScript JavaScript 既可以作为客户端脚本也可以作为服务器端脚本,
但它们除嵌入在html源文件中的方式不同(见上)外, 两端的函数库等也略有不同.
4. B/S 模式中 "客户端脚本" 与 "服务端脚本" 的通信原理
B/S 模式 (Browser/Server) 中连接客户端与服务器的桥梁是 HTTP 协议. HTTP提供了两种最常用的数据
传送方式即: GET和POST (通常 html 中的超级链接都是通过 GET 方法提交数据, 通过表单(form)提供的
数据可以是 POST 方法也可以是 GET).
从上面的原理可以看出, "客户端脚本" 与 "服务端脚本" 如需互相交换数据, 也只通过 GET方法或 POST
方法进行(即 URL或表单). 另外, 除直接通过 URL和表单进行数据传递外, 现在你还可以通过流行 Ajax
技术通过 Javascript与 WebServer 进行异步通信 (它的通信方式类似URL或表单)
5. 小结,
服务器端脚本运行时, 它只会解释执行<% %>或<?php ?%> 之间的脚本语句, 它会把客户端脚本视作
普通文本. 而客户端脚本运行时, 服务器端脚本又是不可见的(客户浏览器上只有服务器端脚本的执行结果).
所以, 服务器端脚本和客户端脚本不能相互直接操作, 也不能相互直接调用.
客户端脚本与服务器脚本交换数据只能通过 GET和 POST 方法(即: URL?查询 和 post 方法)相互传递数据,
客户端脚本还可以通过Ajax, 先异步通信请求服务器动态获取查询结果, 然后再分析查询/输出结果 ..
6. 实例:
下面是一个Javascript 与 CSP(The C Language Service Page) 一起运行示例, 你可以轻易改成用其它语言的实现:
(可直接运行: 把 test.csp 拷贝到 cgi-bin 目录并给预执行权限, 在浏览器输入 http://ip/cgi-bin/test.csp)
说明:
Line4, Line11 是两条 C 语句, Line4 使用 isblankstr()函数判断文本框 "textbox" 中是否输入了数据,
如果输入了数据将输出 Line5-Line9 的 Javascript. 浏览器运行脚本程序, 并弹出对话框: "你输入的是xx".
test.csp 源文件(见附件):
CODE:
1 #!/usr/bin/cspengine
2 <html>
3 <head>
4 <META http-equiv=Content-Type content="text/html; charset=gb2312">
5 <% if (!isblankstr(G("textbox"))) { %>
6 <script language=JavaScript>
7 <!--
8 alert("你输入的是: " + "<% =G("textbox") %>");
9 location.href = "<% =thisCgiPrefix(NULL) %>";
10 -->
11 </script>
12 <% } %>
13 </head>
14 <body>
15 <form method=post action="<% =thisCgiPrefix(NULL) %>">
16 请输入: <input type=text name=textbox><p>
17 <input type=submit name=submit value="提交"><br>
18 </form>
19 </body>
20 </html>
运行结果1, 等待输入:
2 <html>
3 <head>
4 <META http-equiv=Content-Type content="text/html; charset=gb2312">
5 <% if (!isblankstr(G("textbox"))) { %>
6 <script language=JavaScript>
7 <!--
8 alert("你输入的是: " + "<% =G("textbox") %>");
9 location.href = "<% =thisCgiPrefix(NULL) %>";
10 -->
11 </script>
12 <% } %>
13 </head>
14 <body>
15 <form method=post action="<% =thisCgiPrefix(NULL) %>">
16 请输入: <input type=text name=textbox><p>
17 <input type=submit name=submit value="提交"><br>
18 </form>
19 </body>
20 </html>
CODE:
<html>
<head>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
</head>
<body>
<form method=post action="?!=/cgi-bin/gnext.csp&">
请输入: <input type=text name=textbox><p>
<input type=submit name=submit value="提交 "><br>
</form>
</body>
</html>
运行结果2, 输入提交后 :
<head>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
</head>
<body>
<form method=post action="?!=/cgi-bin/gnext.csp&">
请输入: <input type=text name=textbox><p>
<input type=submit name=submit value="提交 "><br>
</form>
</body>
</html>
CODE:
<html>
<head>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<script language=JavaScript>
<!--
alert("你输入的是: " + "abc123");
location.href = "?!=/cgi-bin/gnext.csp&";
-->
</script>
</head>
<body>
<form method=post action="?!=/cgi-bin/gnext.csp&">
请输入: <input type=text name=textbox><p>
<input type=submit name=submit value="提交 "><br>
</form>
</body>
</html>
<head>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<script language=JavaScript>
<!--
alert("你输入的是: " + "abc123");
location.href = "?!=/cgi-bin/gnext.csp&";
-->
</script>
</head>
<body>
<form method=post action="?!=/cgi-bin/gnext.csp&">
请输入: <input type=text name=textbox><p>
<input type=submit name=submit value="提交 "><br>
</form>
</body>
</html>