来到TX后第一个比较正式的任务就是做一个活动页面。页面就不说了,活动页面嘛,那个线条啊只能大块大块地切图了。然后就是因为数据量并不多,所以采用了用静态页然后通过JS去读数据的做法。然后就碰到了跨域的问题了。
我想肯定有很多朋友也会碰到这样的情况,对方只给出一个链接让你去取数据,通过传递不同的参数,返回不同的数据。如果是在本域的话,用AJAX是很方便的,但AJAX不能跨域。而iframe的方法也不实用,只能跨小域,还需要在双方页面加相应的函数,页面里多了那么一块也让人感觉不舒服。所以决定用动态script标签的方法来解决这个问题。
在这里想说一句,国内的业内环境真是…,网上查出来的技术文章几乎都是同样的几篇转来转去,而且也说得不清不楚的很费解。还是BI上环境好些,呵呵。下面的代码并非我原创,也是参考来的,但我一定讲解清楚,让每一个看这文章的人都能明白具体是如何实现的。
由于浏览器安全的问题,一些跨域的请求都会被拒绝,当然,你也可以设置为添加到信任站点就能访问,但你不可能要求你的每个用户都去这样添加。但是,也有个例外,JS是可以跨域的,比如说我们用jquery的时候,可以加载code.google.com里面的jquery包,同样也能应用到jquery的框架;再比如说一些流量统计的代码,都是加一段JS在页面,我们就能应用到写在里面的函数了。所以,当我们把我们所以跨域读取的地址写在script标签的src里的时候,不管是什么后缀名的文件,都会被当做一个JS来读取。所以呢,这个页面的输出要采用JS的格式。
在这里先说两点,第一是这个方法名字虽然是叫动态script标签,但是你静态地直接写在页面里也是可以的,前提是你不需要动态地传递参数;第二是在很多文章里会把此方法跟json扯上关系,其实这跟json没有任何关系,只是因为用json来处理某些返回值时比较方便罢了。下面还是用json格式的来说明好了,因为这样的应用可能会比较多一点。
首先我们新建一个页面,可以是ASP、PHP或者CGI,或者TXT也都可以,但是让他的输出像这样:
var MyJSON = {
'info': [{'name' : 'moondy','sex' : '男','age' : '28'}]
};
这里定义了一个json,你也可以这样定义:
var name="moondy";
var sex="男";
var age="28";
喜欢怎样写就怎样写了,只是在有多组数据的时候,用json比较方便了。关键是要用var ,这样才能当做一个JS的变量来读取,此方法的主要思想,就是在你的页面动态地加入了一句变量的定义,而你就可以直接在JS中引用这个变量了。下面是JS部分:
var element = document.createElement("script");
function createScript(compId,dataId){
element.src = "http://www.moondyzone.com/json.php";//这里是你需要跨域读取的URL
element.type = "text/javascript";
element.language = "javascript";
}
function writeContent(){
alert(MyJSON[0].name);//可以看到读取了相应的数据,json的操作跟数组类似了。这里就可以直接读取上面var定义的变量了。
}
window.onload = function(){
createScript(1,2);//这里的这个参数是在需要动态传递参数的时候用的,本例中没有用到,看具体的需要了。
document.getElementsByTagName("head")[0].appendChild(element);
}
if(document.all){
element.onreadystatechange = function(){//IE用
var state = element.readyState;
if (state == "loaded" || state == "interactive" || state == "complete") {
writeContent();
}
};
} else {
element.onload = function() {//FF用
writeContent();
};
}
在这里就没有做DEMO了,本人在实际项目中应用都没有问题的了。另外也可以跟据不同的需求进行修改,比如说例子中element.onreadystatechange 是在加载完成后运行,可以自行改为点击触发之类的也都可以咯。不过有一点要注意,动态改变外域的URL时需要刷新页面,直接重写script标签中的src在IE中会读不到。
最近发现有不少通过“AS3 json”关键词搜索过来的朋友,可见还是有很多朋友对这方面关注的。不过现下有关AS3 JSON的文章是少之又少,网上搜索到的基本上也都是那同样的几篇文章转来转去罢了,也包括我之前那篇,也没什么例子。相信会让很多初学的朋友看得云里雾里的,其实我也觉得奇怪,json其实也算蛮简单的,怎么就没人写篇好的教程呢。废话就不多说了,希望转载的朋友能注明一下出处,谢了。
首先,你需要有一个JSON的类库,建议去下载adobe官方提供的产品外类库:as3corelib。类库的使用就不多说了,大家应该都知道。
先说说获取数据。可以这么说,只要你懂AS3与XML的交互,那么就一定能懂JSON,因为两者几乎是一样的,你唯一需要做的只是了解一下JSON的格式。例如下面这个JSON的例子,就像XML一样,你可以通过任何动态页面来生成这个格式,也可以通过静态的甚至TXT来读取也行。
1
2
3
4
| [{"name":"Hans","age":"32"},
{"name":"John","age":"12"},
{"name":"Zaki","age":"34"},
{"name":"Dr. Cox","age":"88"}] |
AS中的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| package {
import com.adobe.serialization.json.JSON;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
public class getJSON extends Sprite {
public function getJSON() {
var loader:URLLoader = new URLLoader();
loader.load(new URLRequest( "http://127.0.0.1/json.php" ));//这里是你要获取JSON的路径
loader.addEventListener(Event.COMPLETE, decodeJSON);
}
private function decodeJSON(evt:Event):void {
var persons:Array = JSON.decode( URLLoader( evt.target ).data );
//在这里,就可以通过操作数组来应用数据了,很方便
for (var i=0; i<persons.length; i++) {
trace( persons[i].name );
}
}
}
} |
是不是很简单呢?在这里我们只用到了decode()这个方法,其实JSON类库要用的也只有两个方法,另一个就是马上要用到的encode()。大家可以理解为编码与解码。发送数据的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| package {
import com.adobe.serialization.json.JSON;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.*;
public class sendJSON extends Sprite {
public function sendJSON() {
var arr : Array = new Array({"name":"Hans","age":"32"},{"name":"John","age":"12"},{"name":"Zaki","age":"34"},{"name":"Dr. Cox","age":"88"});//这里是要发送的数据,可以直接写,也可以是由其他方法生成,不过要注意格式。
sendjson( arr );
}
private function sendjson( a : Array ):void {
var jsonString : String = JSON.encode(a);
var urlVariables:URLVariables = new URLVariables();
urlVariables.json = jsonString;
var urlRequest:URLRequest = new URLRequest(http://127.0.0.1/json.php); //这里是接收数据的动态页。
urlRequest.method = URLRequestMethod.POST;
urlRequest.data = urlVariables;
//其实到这已经结束了,下面的XML只是测试结果而已。
var urlLoader:URLLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, onURLLoaderCompleteEvent);
urlLoader.load(urlRequest);
}
private function onURLLoaderCompleteEvent( evt : Event ):void {
var xml:XML = new XML(evt.target.data);
trace(xml);
}
}
} |
以往在做FLASH数据交互的时候,大多用的是XML,或者直接通过html传递参数来交互。前不久接触了一下JSON,研究了一下,觉得还是值得写点东西的。
json是JavaScript Object Notation的简写,是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它是基于JavaScript(Standard ECMA-262 3rd Edition – December 1999)的一个子集,也就是说他是来自于javascript的东西。因为现在ajax的流行,大部分网站会采用ajax的模式和构架,那么json会是一个数据传输的首选(文本方式太简单,要是大数据量的时候无法理解,xml的方式数据量大,在解析的时候会增加服务器负担),那么要是一个网站从ajax构架的基础上出一个flex/flash版的界面的时候使用json会最少地减少服务器端的程序改动。
JSON的结构写法很容易理解,它原本就是以数据量小和清晰的数据格式而著称的。但是在AS中使用json其实并不是一个必须或是很好的选择,很多时候我们还是会用XML,因为AS对XML的解析已经很好了。但是多了解一种数据交互形式,特别是如此简单的JSON,当然是有益无害的咯。
在这里想说些题外话,很多人喜欢拿XML跟JSON的可读性以及解析来做比较,其实一个写法优秀的XML也不会比JSON差,举个例子来说吧,现假设有一个用户数据包括:用户名、密码、所在部门、性别、年龄。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| 用XML表示如下:
<?xml version="1.0" encoding="utf-8"?>
<user>
<name>张三 </name>
<password>123456</password>
<department>技术部</department>
<sex>男</sex>
<age>30</age>
</user>
对于这样一个XML来说,如果数据量大了的确让人头昏眼花,也不好处理,但是如果我们转化成下面这种形式的话:
<?xml version="1.0" encoding="utf-8"?>
<user>
<people name="张三" password="123456" depattment="技术部" sex="男" age="30" />
</user>
再跟相应该的JSON来比较:
{"name":"张三","password":"123456","department":"技术部","sex":"男","age":"30"}
也不会相差太多咯。 |
下面再说说adobe的官方的JSON类的用法吧。
1、服务器端来的json
语法:JSON.decode(String)
从服务器端获得的应该是一个字符串,把它存入一个变量,然后通过JSON.decode(String)方法后,就可以通过点语法来访问这些值。下面是一个网络上找来的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
| var serverJSON:String = '{ "programmers":{ "firstName": "Brett", "lastName":
"McLaughlin", "email": "brett@newInstance.com" }, "firstName": "Jason",
"lastName":"Hunter", "email": "jason@servlets.com" }, "firstName":
"Elliotte", "lastName":"Harold", "email": "elharo@macfaq.com" }],
"authors": "firstName": "Isaac", "lastName": "Asimov", "genre":
"science fiction" }, "firstName": "Tad", "lastName": "Williams", "genre":
"fantasy" }, "firstName": "Frank", "lastName": "Peretti", "genre":
"christian fiction" }],"musicians": "firstName": "Eric", "lastName":
"Clapton", "instrument": "guitar" },{ "firstName": "Sergei", "lastName":
"Rachmaninoff", "instrument": "piano" }]}'
var s:Object = JSON.decode(serverJSON);
//开始使用
trace(s.programmers[0].firstName);//输出:Brett |
2、本地对象做成JSON
语法:JSON.encode(Object)
其实也就是跟读取相反,创建一个对象然后输出而已了。你可以直接拼写JSON的字符串,也可以通过对象来创建了。
1
2
3
4
5
6
7
| import json.*;
var myObject:Object = new Object();
myObject.ab = "adfsdf";
myObject.cd = Math.random();
trace(JSON.encode( myObject ));
//输出:{"ab":"adfsdf","cd":0.0599129400216043}
这样就可以给服务器了。 |
本民工接触JSON也不久,一些个人看法,如有不对欢迎指正。