首页 | 软件中心 | Designand Inspiration
读库教程网 > 网络教程 > 媒体动画 > Flash > 不可见的Flash:议决运用不可见的FlashPlayer增强Web利用顺序

不可见的Flash:议决运用不可见的FlashPlayer增强Web利用顺序

添加:2010年7月13日


  让我们开端吧
  如前所述,您将在本文中学习如何运用 Flash 为 Web 使用顺序增添额外的功用。熟识 javascript 是必需的技艺,有 ActionScript 运用体会将会很简约。有许多办法编译 ActionScript,其中一些依托于 Adobe 的商业工具。但是,也可以够运用 Adobe 的开源 Flex SDK。本文运用的是 Flex SDK 4.0.0.10485 (Beta 2)。为了运转示例顺序,须要 Flash Player 的第 10 版或更高版本。本文中运用的是 10.0.42.34 版本。
  Flash 本地存储
  许多 Web 使用顺序须要在客户端存储形态。有时分这仅仅是某品种型的会话 ID,它能够用来从内存或数据库检索服务器端形态。但是,许多 Web 使用顺序出于可伸缩性的思索成心防止服务器端形态。因而,一切的形态都要存储在客户端。另外,通常期盼形态在现在回话完毕后仍然坚持。
  耐久以来都运用 HTTP cookies 作为默许的处置方式。但是,HTTP cookies 存在缺陷。在开发人员看来,它难以运用,由于它实践是只是一个 HTTP 头部。更首要的是,存在安全隐患。关于每个央求,HTTP cookies 都会在客户端和服务器端来回传递,因而其中的一切数据都能够被截取。尚有,跨站点脚本/伪造会使用这一特定 “窃取 cookie”。假设 cookies 被窃取了,您的相应账号很能够被破坏甚至被他人使用。
  但是,HTTP cookies 最罕见的缺陷就是大小限定。不一样阅读器为每个域分配的 HTTP cookies 的最大容量是不一样的。HTTP 规范将其限定为 4 KB,这就是您所能使用的一切空间。假设想在客户端存储大于 4 KB 的数据如何办呢?假设您思索过这些疑问,您只好不能地用 Java™Script 编写一个 gip 式的紧缩算法,这是一种办法。或许,能够运用其他替代办法,比如,Flash。
  本地共享对象
  Flash Player 为 Flash 使用顺序提供了本地存储空间。默许情况下,每个域有 100 KB 的限定。这样很好:可获得是 HTTP cookies 的 25 倍的空间。尚有其他一些首要的差异。其一,Flash 中存储的客户端数据不会发送给服务器,由于它与 HTTP 没有任何联系。当然,假设您情愿,也可以够将这些数据发送给服务器。这样做不会有任何障碍。但是,您必需挑选发送哪些数据以及以什么方式发送。假设您真的期盼客户端和服务器都包含这些数据,这就有点庞杂了。但是,这通常愈加安全,由于您必需在网络中显式 “公示” 这些数据。
  用于存储和检索本地数据的 Flash API 是 SharedObject。原本,Flash 的 SharedObject 观点也可以够是远程的,因而,仅存在于客户端的变体也称为本地 SharedObject。该 API 十分容易,它准许运用键-值范式存储和检索恣意庞杂的对象。清单 1 是存储和检索 SharedObjects 的容易代码。
清单 1. 存储和检索 SharedObjects
package{ 
   
  import flash.display.Sprite; 
  import flash.net.SharedObject; 
   
  public class JsHelper extends Sprite{ 
    private const SO_NAME:String = "helperSo"; 
     
    private function saveLocal(name:String, value:Object):void{ 
      var so:SharedObject = SharedObject.getLocal(SO_NAME); 
      so.data[name] = value; 
      so.flush(); 
    } 
     
    private function readLocal(name:String):Object{ 
      var so:SharedObject = SharedObject.getLocal(SO_NAME); 
      return so.data[name]; 
    } 
  } 
} 

  假设您不熟识 ActionScript,清单 1 的代码能够看上去有点奇异。ActionScript 很像 JavaScript;实践上,它来自于 ECMAScript 规范。虽然如此,它具有许多 C++ 和 Java 中罕见的特征。变量都是强类型的,尚有基于类的承袭。清单 1 中的代码是一个扩展了 Sprite 类的类。该类将会编译进 Shockwave Flash (SWF) 文件,此文件会嵌入 Web 页面中。该类有两个办法。其中一个叫 saveLocal。它须要一个称号(只是一个字符串)和一个值(任何类型的对象)。然后它运用 getLocal 工厂办法获得特定的 SharedObject。
  每个 SharedObject 实例都有一个数据属性,能够看作存储数据的哈希表。这就是 saveLocal 函数的第二行的作用。结尾一行 “清理” SharedObject,或将其保管到硬盘上。这些就是本地存储所要做的一切。假设大量运用 SharedObjects 并接近了 100 KB 的限定,那么您能够须要添加事情监听器。这将能够对 “清理完成” 或 “清理失败” 之类的事情做出照应。
  从本地存储中回读一样也很容易,这是议决清单 1 的 readLocal 函数完成的。本例中,已搜索到 SharedObject,并且 name 参数已用于从数据哈希表中搜索已存储的对象。假设哈希表中没有与键值对应的称号,将前往 null。既然已学会如何访问 SharedObjects,如今只须要在 Web 页面上获取 Flash(不可见)— 以及运用 JavaScript 访问它。
  使其不可见
  默许情况下,清单 1 中的任何函数都不能在 JsHelper 类以外访问。但是,Flash 能够很容易地将函数公示给 JavaScript。须要做的就是运用 Flash 的 ExternalInterface API,如清单 2 所示。
清单 2. 将 JsHelper 函数公示给 JavaScript
package{ 
   
  import flash.external.ExternalInterface; 
  import flash.net.SharedObject; 
   
  public class JsHelper extends Sprite{ 
    private const SO_NAME:String = "helperSo"; 
    private const SAVE_LOCAL:String = "saveLocal"; 
    private const READ_LOCAL:String = "readLocal"; 
     
    public function JsHelper(){ 
      ExternalInterface.addCallback(SAVE_LOCAL, saveLocal); 
      ExternalInterface.addCallback(READ_LOCAL, readLocal); 
    } 
    // functions omitted for brevity 
  } 
} 

  清单 2 容易演示了向清单 1 中的 JsHelper 类添加的内容。首要的留意点是添加了一个显式构造函数。正如您所料,这个构造函数将在创立类的一个实例时得到调用。其中,运用 ExternalInterface API 将两个函数 saveLocal 和 readLocal 公示给 SWF 所嵌入的一切 Web 页面上的 JavaScript。addCallback 函数的第一个参数是字符串。JavaScript 客户端运用它作为称号识别函数。它与类中的函数名能够不一样,但在该例中是类似的。第二个参数是一个函数闭包。与 JavaScript 一样,ActionScript 是函数言语,因而函数是一阶的,能够传递。这就是公示两个函数所须要做的。如今看看用于嵌入和访问 SWF 的 JavaScript。详见清单 3。
清单 3. 嵌入不可见 Flash
<!DOCTYPE Html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>Flash Helper for JavaScript</title> 
<script type="text/javascript" src="swfobject.js"></script> 
<script type="text/javascript"> 
  function writeFlash(){ 
    var attrs = {id : "JsHelper"}; 
    swfobject.embedSWF("JsHelper.swf", "flashContainer", "1", "1", "10.0.0", 
      "playerProdUCtInstall.swf", null, null, attrs); 
  } 
  function save(name, value){ 
    var helper = document.getElementById("JsHelper"); 
    helper.saveLocal(name, value); 
  } 
  function load(name){ 
    var helper = document.getElementById("JsHelper"); 
    return helper.readLocal(name);     
  } 
</script> 
</head> 
<body onload="writeFlash()"> 
  <div id="flashContainer"></div> 
</body> 
</html> 

  这段代码中最先要留意的是运用了第三方 JavaScript 库 swfobject。这实践上是嵌入 SWF 的规范库。它是开源的,虽然开始不是由 Adobe 开发的,但是如今由他们维护。它的 embedSWF 函数用于嵌入由清单 2 编译的 SWF。第一个参数是指向 SWF 的 URL。本例中,SWF 来自和 HTML 文件类似的服务器和途径,因而能够运用一个绝对 URL。第二个参数是在其中嵌入 SWF 的页面的 HTML 元素的 ID。本例中是 "flashContainer" — 同时您将留意到 HTML 文档的主体局部有一个 HTML div 运用该 ID。
  接下来的两个 embedSWF 参数是 SWF 的高度和宽度。在本例中,两者的值都是 1。这意味着 SWF 的高度和宽度都为一个像素。这就是不可见的 SWF!下一个参数是 Flash 的最低版本,您的 JavaScript 将检验该参数。假设 Flash 已装置在阅读器上,但其版本号比传递给 embedSWF 的版本号更低,那么 embedSWF 将运用下一个参数 "playerProductInstall.swf"。这是指向另一个 SWF 的 URL,它提示用户装置最新版本的 Flash。关于不可见 Flash,这原本没什么影响 — “您须要装置最新版本 Flash” 的 SWF 原本也不可见(当然,也是 1x1 像素)。传给 embedSWF 的结尾一个参数很首要。这是一个包含各种可选参数的属性对象。其中一个可选参数是 SWF 的 ID。关于和本文类似的用例,该参数是不可选的 — 这至关首要!它将会提供应 SWF 一个 HTML ID,而这将会在运用 JavaScript 举行编程访问时用到。
  如今看看 清单 3 中的两个 JavaScript 函数。二者很类似。都运用熟识的 getElementById 函数获取 SWF 的引用。请留意它们运用的是 writeFlash 函数中的 attrs 对象指定的 ID。获得 SWF 引用后,能够直接调用 清单 2 中公示的 ActionScript 函数。此处的首要是,JavaScript 中运用的函数名必需婚配 ExternalInterface.addCallback 函数中公示的称号或许是传给 addCallback 的第一个参数。
  关于 save 办法,传递了一个 JavaScript 对象作为 value 参数。这能够是恣意对象,甚至能够具有一个深度嵌套的构造。但是,只会传递对象的数据。假设该对象包含函数,那么将不会被传递。请留意 load 办法将前往一切来自 SWF 的内容。是什么内容?答案很容易:您发送的任何内容。假设您存储的是数字或字符串等标量值,那么将前往这些内容。假设存储的是庞杂的对象,那么将前往该 JavaScript 对象 — 不须要分析或其它操作。一个例外是假设对象包含函数,那么必须不会被序列化并保管。因而只会前往对象中的数据,而不是其他内容。以上总结了运用 Flash 举行本地存储所需掌握的所有内容。在学习运用 Flash 操作跨域 Ajax 之前,明白一些可作为替代挑选的本地存储办法。
  其他的本地存储挑选
  我提到 Flash 是面向客户端存储的一个有吸引力的挑选,能够替代 HTTP cookies。虽然如此,尚有两项 Web 技术采用了与 Flash SharedObjects 一样的范式。现实上,耐久以来各种阅读器都提供类似的 API。但各阅读器的 API 不尽类似。因而您能够先明白一下各个阅读器,然后运用特定的 API。Flash 提供了一致的替代方案。本文中开发的代码几乎能够运转于一切阅读器:Internet EXPlorer 6 和 FireFox 2,以及这些阅读器的最新版本。更新的版本提供一致的处置方案。HTML 5 规范包含一个 localStorage API。主流阅读器的最新版本都完成了这个 API,包含 IE 8 和 Firefox 3.5。因而假设只担忧阅读器的话,localStorage 将是一个可用的选项。假设担忧旧的阅读器(IE 6、IE 7 等等),那么运用 Flash 能够会更容易。如今,看看 Flash 能够完成的新功用,跨域 Ajax。
  跨域 Ajax
  Ajax 当前在 Web 使用顺序中无所不在;它是任何 Web 使用顺序中都假定会有的局部。Ajax 的一个首要缺乏就是为人诟病的同源战略。假设 Web 页面由 a.com 提供,您只好向 a.com 调用 Ajax(更精确地说是 XMLHttpRequest)。比如,您不能调用 b.com。假设您的公司拥有 a.com 和 b.com,那就没有影响;阅读器不会关心这些。但是对 Flash 使用顺序却不是这样。
  Flash 使用顺序能够获得容许,并对提供服务的域以外的域举行调用。这能够用跨域战略文件完成。默许情况下,Flash 运转时将在服务器的文档根目录搜索战略文件:http://<your domain>/crossdomain.xml。比如,清单 4 是 Twitter 搜索域的战略文件,http://search.twitter.com/crossdomain.xml
清单 4. Twitter 搜索域的战略文件
<!DOCTYPE cross-domain-policy 
SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd"> 
 
<cross-domain-policy> 
  <allow-Access-from domain="*" /> 
</cross-domain-policy> 

  这是个相当好的战略文件。它准许一切(如 “*” 通配符所示)域对 SWF 举行访问。因而一切 Flash 使用顺序都能够调用 Twitter 的搜索 API。在大非少数具有公共 API 的 Web 站点上像这样的战略文件很罕见。虽然如此,有些站点运用愈加严厉的战略,只准许自己一切的其他域或协作同伴的域举行访问。有了战略文件,就能够细粒度地精确控制谁能够调用服务器,谁不能。看看如何将一样的功用扩展到 Ajax 使用顺序中。
  跨域
  假设您的使用顺序只须要调用特定的域,能够编写 ActionScript 代码调用该域,然后在使用顺序中运用 ExternalInterface 将其公示给 JavaScript。但是,我将采取一种更好的办法,并试图用更普通化的方式举行公示。因而,清单 5 中,将运用一个适用类从 ActionScript 中调用恣意域。
清单 5. 跨域工具 SWF
package{ 
   
  import flash.display.Sprite; 
  import flash.events.Event; 
  import flash.external.ExternalInterface; 
  import flash.net.URLLoader; 
  import flash.net.URLRequest; 
   
  public class JsHelper extends Sprite{ 
    private const SEND_REQUEST:String = "sendRequest"; 
     
    public function JsHelper(){ 
      ExternalInterface.addCallback(SEND_REQUEST, sendRequest); 
    } 
 
    public function sendRequest(url:String, handlerName:String, 
        method:String="GET", content:Object=null, 
        headers:Object=null):void{ 
      var loader:URLLoader = new URLLoader(); 
      var request:URLRequest = new URLRequest(url); 
      if (method){ 
        request.method = method; 
      } 
      if (headers){ 
        for each (var name:String in headers){ 
          request.requestHeaders[name] = headers[name]; 
        } 
      } 
      if (content){ 
        request.data = content; 
      } 
      loader.addEventListener(Event.COMPLETE, 
        function(e:Event):void{ 
          ExternalInterface.call(handlerName, loader.data); 
      }); 
      loader.load(request); 
    } 
  } 
} 

  该类运用 ExternalInterface 将 sendRequest 函数公示给 JavaScript。这在对象的构造函数中完成,和之前 清单 2 中的例子一样。sendRequest 函数有点庞杂:它有两个必需的参数。第一个参数是须要调用的 URL。这是一个完壁的 URL 字符串,包含一切央求参数。下一个是 JavaScript 函数名,此函数在获得服务器照应后由 Flash 调用。和典型的 Ajax 一样,Flash 对远程服务器举行异步伐用,主 UI 线程在等候远程服务器照应时不会中止。因而,与 Ajax 一样,须要编写 callback 函数,它将在接纳到服务器照应后被调用。将其作为字符串传递给 Flash,但它必需与函数名完全类似。
  sendRequest 函数也有三个可选参数。ActionScript 准许有可选参数,但必需有可用的缺省值。第一个是运用 HTTP 办法,通常是 GET 或 POST。本文中,我将它默许为 GET,但是能够很容易地用 POST 将其交流,这取决于远程服务器的须要。下一个可选参数叫做 content。这是一个普通数据对象,包含有须要发送给远程服务器的恣意称号-值对。向远程服务器发送数据时须要用到。结尾一个可选参数是另一个用于头部的普通数据对象。它用于将定制 HTTP 头部配置为作为远程服务器调用的一局部发送。
  然后代码获取一切这些参数,运用 Flash URLRequest 对象构造 HTTP 央求,然后运用 Flash URLLoader 类发送央求。事情监听器会绑定到 URLLoader 以便能处置前往的照应。这里创立一个闭包,仿佛在 JavaScript 中一样,创立一个匿名内联函数,将在 COMPLETE 事情被加载顺序触发后调用。该闭包将只运用 ExternalInterface 来调用称号被传递给 sendRequest 的函数。它未来自远程服务器的一切数据传递给该函数。这显然比运用本地存储庞杂一点。看看清单 6 中调用 Twitter 搜索的例子。
清单 6. 调用 Twitter 搜索
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>Calling Twitter from the client</title> 
<script type="text/javascript" src="swfobject.js"></script> 
<script type="text/javascript"> 
  function writeFlash(){ 
    var attrs = {id : "JsHelper"}; 
    swfobject.embedSWF("JsHelper.swf", "flashContainer", "1", "1", "10.0.0", 
      "playerProductInstall.swf", null, null, attrs); 
  } 
  function search(){ 
    var keyWord = document.getElementById("keyword").value; 
    var helper = document.getElementById("JsHelper"); 
    helper.sendRequest("http://search.twitter.com/search.json?q=" + keyword, 
"showResults"); 
  } 
  function showResults(responseStr){ 
    var response = eval("(" + responseStr +")"); 
    var results = response.results; 
    alert("#Results = " + results.length); 
  } 
</script> 
</head> 
<body onload="writeFlash()"> 
  <div id="flashContainer"></div> 
  <div id="inputDiv"> 
    <label for="id">Search Twitter</label> 
    <input type="text" id="keyword" name="keyword"/> 
    <input type="button" value="Search Twitter" onclick="search()"/> 
  </div> 
</body> 
</html> 

读库教程网文章由网络收集后整理发布,文章发布人拥有该内容的所有权力及责任!

如果你喜欢这页,可以按Ctrl+D收藏起来。

相关内容
上一个内容:FlashAS3.0实例教程:喷泉动画不凡收获
下一个内容:Has no
相关评论
公益广告
精彩推荐
友情链接: 百分百青年 | 烛光信息网 | 夏布新网 | 新育互联网
管理员:QQ:27038219, E-mail:27038219@qq.com今日更新
读库教程网所有文章从网络收集所发布,文章发布人拥有该内容的所有权力及责任,转载时请注明出处!
Template designed by www.dkuu.com. Optimized for 1024x768 to Firefox,Opera and MS-IE6/IE7.