不用 iframe 和 SSI 能否实现包含页(转贴)

本文探讨了在不使用iframe和SSI的情况下实现页面包含的方法。通过download行为结合innerHTML属性来加载并显示指定文件的内容,并提供了多种替代方案,包括script标签、Object标签、XMLHTTP组件等。

不用 iframe 和 SSI 能否实现包含页(转贴)

原地址:http://www2.flash8.net/teach/4014.htm

主要是asp下面的实现。很多都可以在其他地方应用。

不用 iframe 和 SSI 能否实现包含页

作者:闪吧   类型:原创   来源:闪吧
style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; WIDTH: 400px; PADDING-TOP: 0px; HEIGHT: 25px" src="teachInfo.aspx?id=4014" frameborder="0" scrolling="no">
   不用 iframe 和 SSI 能否实现包含页
解决思路
可以用 download 行为下载后再用 innerHTML 特性显示出来。
具体步骤
1.调用页代码。

<span id="demo" src="demo.htm" _fcksavedurl=""demo.htm"" _fcksavedurl=""demo.htm""
 style="behavior:url(#default#download)"></span> 
<SCRIPT>
 function window.onload(){
   demo.startDownload(demo.src,fnDownload)
 }
 function fnDownload(oSource){
   demo.innerHTML=oSource
 }
 </SCRIPT>
    
2.被调用页demo.htm的代码。
    
<span style="color:red;font:bold 12px Tahoma">
测试 演示 TEST test DEMO demo</span>

注意:在本例中id为demo的对象必须设置它的默认行为为download。
技巧:笔者总结的包含调用文件的9种方法:
1.script。需要注意的是include.js里不能再包含<script>和</script>,扩展名随意,所有内容必须经由 write()、wirteln()、innerHTML、innerText、outerHTML或outerText 输出显示。代码示例:

<script src="include.js"></script>

2.iframe。这个不用多解释了,有疑问的话请第一部分第六章。代码示例:

<iframe src="index.asp"></iframe>

3.Object(Scriptlets组件)。代码示例:

 有滚动条<br>
 <object data="index.asp" type="text/html" width=400 height=300></object>
 <br>无滚动条<br>
 <object style="border: 0px" type="text/x-scriptlet" data="index.asp" width=400 Height=300></object>

4.SSI(服务器端包含)。代码示例:

<!--#include file="index.asp"-->
<!--#include virtual="/index.asp"-->

5.Server.Transfer,Server.Execute(ASP对象的方法)。代码示例:

server.execute ("index.asp")
server.transfer ("index.asp")

6.FSO(FileSystemObject,文件读写组件)代码示例:

<%
 TF=Server.Mappath("index.asp")
 set fs=server.createobject("scripting.filesystemobject")
 set ts=fs.opentextfile(TF)
 Do While(ts.atendofstream<>true)
 response.write(ts.readline)
 Loop
 ts.close
%>
7.download 行为。代码示例:

<span id="demo" src="demo.htm"
 style="behavior:url(#default#download)"></span> 
<SCRIPT>
 function window.onload(){
   demo.startDownload(demo.src,fnDownload)
 }
 function fnDownload(oSource){
   demo.innerHTML=oSource
 }
 </SCRIPT>

8.XMLHTTP组件。代码示例:

<script for="window" event="onload">
  with(new ActiveXObject("Microsoft.XMLHTTP")){
  open("get",demo.src,false,"","")
  send()
  demo.innerHTML=ResponseText
  }
</script>
 <span id="demo" src="demo.htm"></span>

需要注意,目标文件最好以Unicode或UTF-8编码保存,否则目标文件中的双字节文字会变成乱码。当然,可以用下面的函数把返回的ResponseText处理一下,但是这样效率比较低,文件较大时不推荐使用。XMLHTTP这种方法也可以在后台程序中使用。

<script language=vbscript>
function bytes2bstr(vin) 
 strreturn = "" 
 for i = 1 to lenb(vin) 
 thischarcode = ascb(midb(vin,i,1)) 
 if thischarcode < &h80 then 
  strreturn = strreturn & chr(thischarcode) 
 else 
  nextcharcode = ascb(midb(vin,i+1,1)) 
  strreturn = strreturn & chr(clng(thischarcode) * &h100 + cint(nextcharcode)) 
  i = i + 1 
 end if 
 next 
 bytes2bstr = strreturn 
end function
</script>

9.HTC(HTML Component,将在下一章中介绍)。
(1)包含页代码。

<span style="behavior:url(index.htc)"></span>

(2)被包含页index.htc的代码。

<public:attach event="oncontentready" onevent="loadit()" />
<script>
function loadit(){
 insertAdjacentHTML("afterBegin", include.innerHTML)
}
</script>
<xmp id="include">
被包含内容
<a href=http://www.flash8.net>flash8</a>
</xmp>

特别提示
本例代码运行效果如图2.4.5所示,页面中所显示的文字为demo.htm页的。

图2.4.5 download行为应用效果
特别说明

download 行为的作用是下载文件并在下载完成后通知一个指定的回调函数,该行为只有一个startDownload方法:
startDownload 下载指定文件,该方法带两个参数,第一个参数为指定下载的文件地址,第二个参数为下载完成后要执行的代码的函数的指针。如果调用的函数是用 VBScript 脚本编写,需要使用 GetRef 函数获取此回调函数的指针。
   责任编辑:kissall    时间:2005年8月29日
<think>我们正在讨论如何结合SSI(ServerSideIncludes)AJAX(AsynchronousJavaScriptandXML)技术实现面局部刷新。引用[2]中提到了SSI模块Nginx中获取时间的方法,这提示我们可以利用SSI在服务器端包含动态内容。但是,AJAX是客户端技术,通常通过JavaScript异步请求数据来更新面局部内容。结合思路:1.我们可以使用SSI来生成面的静态框架(例如包含一些基本不变的部分),并在需要动态刷新的位置放置一个容器。2.然后,在这个容器内,我们可以使用AJAX技术来动态加载内容,而不需要重新加载整个面。具体步骤:步骤1:在HTML面中,使用SSI包含一个静态部分,同时为需要动态刷新的部分预留一个容器(例如一个div元素)。步骤2:编写JavaScript代码,使用AJAX向服务器发送请求,获取需要动态更新的内容,并将其插入到预留的容器中。示例:假设我们有一个面,其中包含一个需要显示当前时间的部分,这个时间需要每秒更新一次。方法1:完全使用SSI(但SSI是服务器端包含,每次都需要服务器重新生成整个面,不适合高频刷新,因为会加重服务器负担,且无法局部刷新)方法2:使用AJAX(推荐)来局部更新时间部分。但是,如果我们要结合SSIAJAX,我们可以这样:首先,我们使用SSI来生成面的整体框架,包括那个用于显示时间的容器。然后,用AJAX来填充更新这个容器。示例代码:第一步:使用SSI面(例如index.shtml)注意:SSI文件通常扩展名为.shtml,并且服务器需要配置支持SSI。```html<!--index.shtml--><!DOCTYPEhtml><html><head><title>SSIandAJAXExample</title><script>//当面加载完成后,启动定时器每秒更新时间window.onload=function(){setInterval(updateTime,1000);//每秒调用一次updateTime函数};functionupdateTime(){//创建XMLHttpRequest对象varxhr=newXMLHttpRequest();//配置请求:GET方法,请求一个返回当前时间的服务器脚本(例如time.php)xhr.open('GET','get-time.php',true);xhr.onreadystatechange=function(){if(xhr.readyState==4&&xhr.status==200){//将返回的时间字符串放入id为'time-container'的元素中document.getElementById('time-container').innerHTML=xhr.responseText;}};xhr.send();}</script></head><body><h1>Welcometoourwebsite!</h1><!--使用SSI包含一个静态部分,例如导航栏--><!--#includevirtual="header.html"--><p>下面是动态刷新的时间:</p><divid="time-container"><!--初始时间可以由SSI提供,但后续由AJAX更新--><!--我们可以使用SSI来显示初始时间,但注意SSI只在服务器端执行一次--><!--#configtimefmt="%Y-%m-%d%H:%M:%S"--><!--#echovar="DATE_LOCAL"--></div><!--注意:上面的SSI会显示服务器时间,但一旦面发送到客户端,这个时间就固定了。所以后续更新需要AJAX。--><!--实际上,我们可能希望初始时间也通过AJAX获取,这样保持一致。因此,我们可以在面加载时立即调用一次updateTime(),或者将SSI部分去掉,完全由AJAX负责。--><!--修改:我们去掉SSI显示时间,完全用AJAX来填充。--><!--所以将上面的div内容改为空,然后通过JS来更新--></body></html>```第二步:服务器端脚本(例如get-time.php)返回当前时间字符串```php<?php//设置响应头为纯文本header('Content-Type:text/plain');//输出当前时间,格式为年月日时分秒echodate('Y-m-dH:i:s');?>```注意:上面的例子中,我们使用了一个简单的PHP脚本来返回时间。你也可以用其他服务器端语言(如Node.js,Python等)实现。但是,我们也可以利用SSI来提供初始时间,然后后续更新用AJAX。不过,由于SSI只在服务器端生成面时执行一次,而AJAX可以多次更新,所以通常我们让初始时间也通过AJAX获取,这样避免面加载时出现时间不一致(因为SSI生成时间AJAX第一次获取时间可能有微小差异)。修改后的index.shtml:```html<!--index.shtml--><!DOCTYPEhtml><html><head><title>SSIandAJAXExample</title><script>//当面加载完成后,先立即更新一次时间,然后启动定时器每秒更新window.onload=function(){updateTime();//立即调用一次setInterval(updateTime,1000);//每秒调用一次};functionupdateTime(){varxhr=newXMLHttpRequest();xhr.open('GET','get-time.php',true);xhr.onreadystatechange=function(){if(xhr.readyState==4&&xhr.status==200){document.getElementById('time-container').innerHTML=xhr.responseText;}};xhr.send();}</script></head><body><h1>Welcometoourwebsite!</h1><!--#includevirtual="header.html"--><p>当前时间:</p><divid="time-container"></div><!--初始为空,由JS填充--></body></html>```这样,我们结合了SSI(用于包含静态的header.html)AJAX(用于动态更新时间部分)。总结:-SSI用于在服务器端组装面的静态部分(例如眉、脚等),这样可以减少重复代码。-AJAX用于在客户端动态更新面中的特定部分,实现无刷新更新。注意事项:1.确保服务器配置支持SSI(对于Apache,需要启用mod_include;对于Nginx,需要安装http_ssi_module模块)。2.AJAX请求的URL(如get-time.php)需要正确设置,并确保服务器能够处理该请求。3.由于AJAX是异步的,所以更新不会阻塞面。另外,引用[2]中提到了Nginx的SSI模块变量$date_gmt,我们可以利用这个变量在SSI中输出时间,但同样,SSI输出的时间在面生成后就不会改变。所以对于需要持续更新的时间,我们仍然使用AJAX。如果我们希望初始时间也由SSI提供,然后后续更新用AJAX,那么我们可以这样写:```html<divid="time-container"><!--#configtimefmt="%Y-%m-%d%H:%M:%S"--><!--#echovar="DATE_LOCAL"--></div>```然后在AJAX更新时覆盖这个时间。但是,这样在面刚加载时会有一次服务器时间,然后很快被AJAX请求的时间覆盖(可能会有1秒的延迟)。如果网络延迟,用户可能会看到时间跳动。所以,为了更好的用户体验,建议初始时间也通过AJAX获取。因此,我们选择在面加载时立即通过AJAX获取时间,然后每秒更新。这样时间显示是连续的,并且避免了SSIAJAX时间不一致的问题。以上示例展示了如何结合SSIAJAX实现局部刷新。SSI负责静态包含,AJAX负责动态数据。相关问题:1.如何配置Nginx或Apache以支持SSI?2.使用AJAX时如何处理跨域请求?3.除了AJAX,还有哪些技术可以实现面局部刷新?</think>### 结合 SSI AJAX 实现面局部刷新的方法 SSI(Server Side Includes) AJAX 可以协同工作实现高效局部刷新:**SSI 负责初始面框架静态内容组装,AJAX 负责动态数据获取局部更新**。以下是具体实现方案: #### 核心实现步骤 1. **SSI 构建基础框架** ```html <!-- index.shtml --> <!DOCTYPE html> <html> <head> <title>SSI+AJAX 示例</title> <script src="ajax-handler.js"></script> </head> <body> <!--#include virtual="header.html"--> <!-- SSI静态包含 --> <div id="dynamic-content"> <!-- 初始内容由SSI提供 --> <!--#config timefmt="%Y-%m-%d %H:%M:%S"--> 最后更新: <!--#echo var="DATE_LOCAL"--> </div> <button onclick="loadData()">刷新数据</button> </body> </html> ``` 2. **AJAX 动态更新容器** (ajax-handler.js) ```javascript function loadData() { const xhr = new XMLHttpRequest(); xhr.open("GET", "/api/dynamic-data", true); xhr.onload = function() { if (xhr.status === 200) { // 局部更新SSI创建的容器 document.getElementById("dynamic-content").innerHTML = xhr.responseText; } }; xhr.send(); } // 可选:自动刷新(每30秒) setInterval(loadData, 30000); ``` 3. **服务器端响应** (Nginx 配置示例) ```nginx location /api/dynamic-data { ssi on; # 启用SSI处理 add_header Last-Modified $date_gmt; # 引用[2]的时间变量 proxy_pass http://backend-service; } ``` #### 关键优势 1. **性能优化** - SSI 减少重复 HTML 传输(适合静态区块) - AJAX 最小化数据传输量(仅更新变化部分) 2. **内容更新逻辑** ```mermaid graph LR A[用户请求] --> B[SSI组装基础面] B --> C[浏览器加载框架] C --> D[AJAX请求动态内容] D --> E[服务器生成新内容] E --> F[局部更新DOM节点] ``` 3. **时间同步技巧** 结合引用[2]的 Nginx 时间变量: ```nginx location /api/time { return 200 "当前服务器时间: $date_gmt"; # 直接输出时间 } ``` #### 注意事项 1. **SSI 配置要求** - Apache:启用 `mod_include` - Nginx:配置 `ssi on;` - 文件扩展名需为 `.shtml` 2. **AJAX 缓存控制** ```javascript xhr.open("GET", "/api/data?" + new Date().getTime(), true); // 避免缓存 ``` 3. **错误处理增强** ```javascript xhr.onerror = function() { document.getElementById("dynamic-content").innerHTML = "更新失败"; }; ``` --- ### 相关问题 1. 如何避免 SSI AJAX 结合时出现内容闪烁? 2. 在哪些场景下 SSI+AJAX 方案比单应用 (SPA) 更合适? 3. 如何用 WebSocket 替代 AJAX 实现实时局部更新? 4. Nginx 的 SSI 模块支持哪些高级包含指令?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值