使用 PHP 代理从 del.icio.us API 装载 XML
因为浏览器内置的安全限制不允许从外部 URL 装载 Web 页面(例如,在访问 google.com 时,通过 Ajax 装载 yahoo.com),所以必须通过代理实现 del.icio.us API。PHP 的 CURL 很适合完成这个任务。下面就来实现代理。
下面要创建的代理的作用仅仅是获取一个 URL 的内容并向用户显示,不做任何进一步处理。创建新文件 proxy.php 并把它保存在 superPage.html 文件所在的目录中。按照清单 5 定义代理。
<?
php
function
getContent(
$url
){
$curl
=
curl_init();
$deliciousUser
=
'
your_username_here
'
;
$deliciousPass
=
'
your_password_here
'
;
$header
[
0
]
=
"
Accept:text/xml,application/xml,application/xhtml+xml,
"
;
$header
[
0
]
.=
"
text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
"
;
$header
[]
=
"
Cache-Control:max-age=0
"
;
$header
[]
=
"
Connection:keep-alive
"
;
$header
[]
=
"
Keep-Alive:300
"
;
$header
[]
=
"
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.7
"
;
$header
[]
=
"
Accept-Language:en-us,en;q=0.5
"
;
$header
[]
=
"
Pragma:
"
;
curl_setopt(
$curl
,
CURLOPT_URL
,
$url
);
curl_setopt(
$curl
,
CURLOPT_USERAGENT
,
"
imTestingAnApp
"
);
curl_setopt(
$curl
,
CURLOPT_HTTPHEADER
,
$header
);
curl_setopt(
$curl
,
CURLOPT_REFERER
,
'
http://www.my-homepage.com
'
);
curl_setopt(
$curl
,
CURLOPT_ENCODING
,
'
gzip,deflate
'
);
curl_setopt(
$curl
,
CURLOPT_AUTOREFERER
,
true
);
curl_setopt(
$curl
,
CURLOPT_RETURNTRANSFER
,
1
);
curl_setopt(
$curl
,
CURLOPT_CONNECTTIMEOUT
,
5
);
curl_setopt(
$curl
,
CURLOPT_TIMEOUT
,
5
);
curl_setopt(
$curl
,
CURLOPT_USERPWD
,
$deliciousUser
.
"
:
"
.
$deliciousPass
);
curl_setopt(
$curl
,
CURLOPT_SSL_VERIFYPEER
,
false
);
curl_setopt(
$curl
,
CURLOPT_SSL_VERIFYHOST
,
false
);
curl_setopt(
$curl
,
CURLOPT_GET
,
1
);
$html
=
curl_exec(
$curl
);
$info
=
curl_getinfo(
$curl
);
curl_close(
$curl
);
$return
[
'
response
'
]
=
$html
;
$return
[
'
info
'
]
=
$info
;
return
$return
;
}
header
(
"
Content-Type:text/xml
"
);
$url
=
urldecode
(
$_GET
[
'
url
'
]);
$url2
=
$_GET
[
'
url2
'
]
!=
''
?
'
?url=
'
.
str_replace
(
'
'
,
'
+
'
,
$_GET
[
'
url2
'
])
:
''
;
$description
=
$_GET
[
'
description
'
]
!=
''
?
'
&description=
'
.
stripslashes
(
str_replace
(
'
'
,
'
+
'
,
$_GET
[
'
description
'
]))
:
''
;
$tags
=
$_GET
[
'
tags
'
]
!=
''
?
'
&tags=
'
.
str_replace
(
'
'
,
'
+
'
,
$_GET
[
'
tags
'
])
:
''
;
$extended
=
$_GET
[
'
extended
'
]
!=
''
?
'
&extended=
'
.
stripslashes
(
str_replace
(
'
'
,
'
+
'
,
$_GET
[
'
extended
'
]))
:
''
;
$old
=
$_GET
[
'
old
'
]
!=
''
?
'
?old=
'
.
$_GET
[
'
old
'
]
:
''
;
$new
=
$_GET
[
'
new
'
]
!=
''
?
'
&new=
'
.
$_GET
[
'
new
'
]
:
''
;
$tag
=
$_GET
[
'
tag
'
]
!=
''
?
'
?tag=
'
.
str_replace
(
'
'
,
'
+
'
,
$_GET
[
'
tag
'
])
:
''
;
$url
=
$url
.
$url2
.
$description
.
$tags
.
$extended
.
$old
.
$new
.
$tag
;
if
(
$url
!=
''
){
$data
=
getContent(
$url
);
echo
$data
[
'
response
'
];
}
?>
首先请注意 getContent 函数中的 $header 变量。在这里设置头部基本上是为了尽可能地模拟浏览器。然后设置几个 curl 选项,其中一些选项不是必需的,但是您应该注意以下选项:
-
CURLOPT_URL—— 指定要获取哪个 URL 的内容。 -
CURLOPT_USERAGENT—— 指定请求 Web 页面的用户代理。del.icio.us 指出一些默认的用户代理有时候会被阻塞,所以最好创建自己的用户代理。 -
CURLOPT_USERPWD—— 在这里指定 del.icio.us 帐户的用户名和密码。 -
CURLOPT_GET—— 指定使用GET方法发出请求。注意,对于添加或删除书签等操作,GET不一定是合适的请求方法,但是因为将用 JavaScript 处理代理 URL,通过链接删除书签的可能性不大。
接下来,注意 清单 5 中 getContents 函数后面的代码。首先,按照 JavaScript XML DOM 解析器的要求发送头部(“text/xml”)。然后按照 API 调用的要求,从 GET 请求(稍后将用 JavaScript 实现请求)获取 URL 和其他变量。最后,重新构造 URL 并把 URL 传递给 getContent($url) 函数。
接下来,看看从给定的 URL 装载 XML 和传递回 XML 文档的代码。
正如在前面看到的,用来填充哈利波特读书俱乐部超级页面中的数据的许多 del.icio.us API 都返回 XML。因此,需要把 XML 装载进 JavaScript Document Object Model(DOM)中,从而获得所需的数据并在适当的 div 元素中显示。接下来,在 superPage.html 页面中定义 JavaScript 代码,见清单 6。
<
title
>
MySuperdel.icio.usWebPage
</
title
>
...
<
scriptsrc
=
"
http://maps.google.com/maps?file=api&v=2&key=
ABQIAAAAXpDdw53sBIu0TzqJscmbxhSKosI2eZOba2P8iIPEPpIkOLlzQhTmc61yB7db5hq2aItkrpqUFq-y3Q
"
type
=
"
text/javascript
"
></
script
>

<
scripttype
=
"
text/javascript
"
>


function
loadXML(fileName)
...
{
varxmlDoc;
if(window.ActiveXObject)...{
xmlDoc=newActiveXObject("Microsoft.XMLDOM");
}
elseif(document.implementation&&
document.implementation.createDocument)...{
xmlDoc=document.implementation.createDocument("","",null);
}
else...{
alert('Unsupportedbrowser');
}
xmlDoc.async=false;
xmlDoc.load(fileName);
return(xmlDoc);
}
首先要包含一个 Google JavaScript 文件,这个文件支持装载不需要任何 XML 处理的 Web 页面。下面的 loadXML 函数是一个跨浏览器(Mozilla、Internet Explorer)的 JavaScript 函数,它用来装载返回 XML 的 URL(fileName)。最后要记住一点,只能把先通过代理的 URL 传递给这个函数,否则这个函数不起作用。
接下来,编写在 清单 3 中首次出现的 showHTML 函数,在浏览器面板中装载 Web 页面。
既然已经建立了通过代理装载 XML 的 JavaScript 功能,现在要创建一个通过代理装载 Web 页面的函数。编写清单 7 所示的 JavaScript 代码。
function
getResponse(url,type)
...
{
GDownloadUrl(url,function(response,responseCode)...{
if(type=='HTTPcontent')
document.getElementById("HTMLcontent").innerHTML=response;
elseif(type=='senddata')
alert(response);
});
}


function
showHTML()
...
{
varurl="proxy.php?url=";
url=url+document.getElementById('currentHTMLpage').value;
getResponse(url,'HTTPcontent');
}
首先看一下 showHTML。这个函数设置一个指向 PHP 代理脚本的 URL。然后,把页面顶部的文本框(见 图 3 和 图 5)中请求的 URL 附加到代理 URL 的末尾,并调用 getResponse 函数。注意,getResponse 函数调用 Google JavaScript 库中的一个函数。当 Google 函数返回数据时,调用内部函数,把 HTMLcontent div 的 HTML 设置为响应,从而显示 图 3 所示的页面。
现在已经编写了 Web 页面浏览器所需的所有功能。您可以试着在哈利波特读书俱乐部超级页面中装载 Web 页面了!
接下来,要开始使用 del.icio.us Web API 了!
使用 API
tags API 可以获取和重命名读书俱乐部的标记。在本节中,我们要定义 reload 函数(见 清单 3)和 renameTags 函数(见 清单 4),还要开始定义 processXML 函数。首先使用 Get 函数。
使用 tags API 的 Get 函数装载读书俱乐部 del.icio.us 帐户中的所有标记,并在超级页面上依次显示它们。定义清单 8 所示的 JavaScript。
function
reload()
...
{
setTimeout("reload2()",4000);
}


function
reload2()
...
{
varurl="proxy.php?url=https://api.del.icio.us/v1/tags/get";
varxmlDoc=loadXML(url);
varstring=processXML(xmlDoc,"tags");
document.getElementById("tags-div-1").innerHTML=string;
string=processXML(xmlDoc,"renameTags");
document.getElementById("tags-div-2").innerHTML=string;
document.getElementById("links-div-1").innerHTML='';
document.getElementById("links-div-2").innerHTML='';
}
这里有两个函数。第一个函数 reload() 在修改标记或删除链接之后调用,用来获取帐户中当前的标记。注意,这个函数仅仅在 4 秒的延迟之后调用 reload2()。reload2() 函数使用 tags/get URL 获取 del.icio.us 帐户中的所有标记。然后,在适当的 div 元素中显示它们。
在清单 8 的 reload2() 函数中,还要注意两个 processXML 函数调用中的第二个参数。这允许使用一个函数实现相似的目标。我们将用这个函数构造 HTML 来替换以下 div 元素:tags-div-1 和 tags-div-2。processXML 函数的定义见清单 9。
function
processXML(xmlDoc,type)
...
{
if(type=='tags')...{
vartagStr='';
vartags=xmlDoc.getElementsByTagName("tag");
for(vari=0;i<tags.length;i++)...{
vartagName=tags.item(i).getAttribute('tag');
tagStr=tagStr+'<inputtype="checkbox"name="'+tagName+'"/>'+
tagName+"<br/>";
}
returntagStr;
}
elseif(type=='renameTags')...{
vartagStr='';
vartags=xmlDoc.getElementsByTagName("tag");
for(vari=0;i<tags.length;i++)...{
vartagName=tags.item(i).getAttribute('tag');
tagStr=tagStr+'<inputsize="10"name="'+tagName+'"/>'+
"<br/>";
}
returntagStr;
}
...
在 清单 8 中调用 loadXML,装载 xmlDoc;然后调用 processXML 执行解析(type 参数设置为 tags)。然后从文档中获取名为 tag 的所有子元素,为每个 tag 创建一个 HTML 输入元素,其中包含一个 checkbox 和 tagname(这些内容依次保存在 tagStr 中)。循环遍历所有标记元素之后,返回 tagStr 并把它设置为 id 是 tags-div-1 的 div 的 HTML 内容。然后第二次调用 processXML 函数(renameTags 作为 type 属性),获取用于标记重命名的文本框,把这个调用的结果设置为 id 是 tags-div-2 的 div 的 HTML 内容。reload2() 函数最后清空显示书签的 div 元素。
以上代码的效果见图 6。
可以看到,在 tags-div-1 div 元素中显示每个标记和复选框,在 tags-div-2 div 元素中显示用于重命名每个标记的输入框。
接下来,看看处理 RENAME TAGS! 按钮所需的代码。
为了重命名读书俱乐部中的标记,需要实现 renameTags 函数。按照清单 10 定义这个函数。
function
renameTags()
...
{
varurl="proxy.php?url=https://api.del.icio.us/v1/tags/rename";
inputTags=document.getElementById("tags-div-2")
.getElementsByTagName("input");
for(vari=0;i<inputTags.length;i++)...{
vartag=inputTags.item(i);
if(tag.value!='')...{
varsendUrl=url+'&old='+tag.getAttribute('name')+
'&new='+tag.value;
getResponse(encodeURI(sendUrl),'senddata');
}
}
reload();
}
在 图 6 所示的文本框中输入新的标记名(非空)之后,通过文本框的名称(tag.getAttribute('name'))获得当前名称,通过文本框的值(tag.value)获得新的名称。然后,设置要发送给代理的 URL,对 URL 进行编码并以 senddata 作为类型调用 getResponse。注意,这仅仅在一个 JavaScript 弹出窗口中显示代理返回的结果。最后,通过 reload() 函数重新装载标记。
为了测试重命名功能,在第一个框中输入 dealio(见 图 6)并单击 RENAME TAGS!。应该会看到图 7 所示的 JavaScript 弹出窗口。
图 7. 成功的标记重命名
另外,超级页面的 tags-div-1 和 tags-div-2 div 元素应该会成功地重新装载,显示重命名后的标记,见图 8.
图 8. 重命名后的标记
接下来,看看如何实现 posts API 来管理哈利波特书签。
PHP代理与del.icio.us API
本文介绍如何使用PHP代理从del.icio.us API获取XML数据,并通过JavaScript解析显示。涉及CURL设置、XML处理及标记重命名等功能。

166

被折叠的 条评论
为什么被折叠?



