李威 さぽている

小说翻译,日语相关转移至http://blog.hjenglish.com/liwei

2010年8月1日 #

JSONP 跨域原理小解

最近看一些代码时,边看边改代码,发现getJSON这个方法没法正常使用。

1 var sURL= "http://api.xxxxxx.com/services/feeds/   
2    xxxxxxx?format=json&callback=?";
3 $.getJSON(sURL, function(data) {
4 // do something with the JSON data returned
5 }); // end get

究其原因,发现url里有个callback,这里使用的是JSONP,一种跨域技术。
网上搜了下JSONP,多数都是在讲如何使用,而没有说明为什么它能跨域,且没有说明url服务器端的代码时如何生成的。
http://www.west-wind.com/weblog/posts/2007/Jul/04/JSONP-for-crosssite-Callbacks
这方面,上面的文章里有比较详细的描述。

 1 function jsonp(url,callback,name, query)
 2 {                
 3     if (url.indexOf("?"> -1)
 4         url += "&jsonp=" 
 5     else
 6         url += "?jsonp=" 
 7     url += name + "&";
 8     if (query)
 9         url += encodeURIComponent(query) + "&";   
10     url += new Date().getTime().toString(); // prevent caching        
11     
12     var script = document.createElement("script");        
13     script.setAttribute("src",url);
14     script.setAttribute("type","text/javascript");                
15     document.body.appendChild(script);
16 }

客户端的javascript代码会有如上的操作,代码不难,很容易理解,也就是加了一个script标签。

而服务器端会返回
callbackFunction( { "x": 10, "y": 15} );
这样的数据。这其实是一段javascript代码,
callbackFunction是方法名,
{ "x": 10, "y": 15}是参数。客户端代码里必须要有
callbackFunction方法的定义。

 1 public partial class JSONP : System.Web.UI.Page
 2 {
 3     protected void Page_Load(object sender, EventArgs e)
 4     {
 5         if (!string.IsNullOrEmpty(Request.QueryString["jsonp"]) )
 6             this.JsonPCallback();
 7     }
 8 
 9     public void JsonPCallback()
10     {
11         string Callback = Request.QueryString["jsonp"];
12         if (!string.IsNullOrEmpty(Callback))
13         {
14             // *** Do whatever you need
15             Response.Write(Callback + "( {\"x\":10 , \"y\":100} );");
16         }
17 
18         Response.End();
19     }
20 }

之后客户端会调用callbackFunction
使用JQuery的getJSON方法后,callback部分会变成如下形式。
callback=jQuery1710461701650187642_1326201333794&_=1326201356534
callbackFunction自然就是
jQuery1710461701650187642_1326201333794部分了。
返回来的数据也会是jQuery1710461701650187642_1326201333794( { "x": 10, "y": 15} ) 这种形式。

最后JQuery会调用匿名函数
function(data),data即为json数据。

JQuery已经将客户端部分实现了,服务器端也得遵循同样的规则才能实现跨域。


*这里有一点,JQuery如何将匿名函数换名字的?有哪位大侠知道的,请用简单的语言讲解下。

posted @ 2012-01-10 21:30 李威 阅读(336) | 评论 (0)编辑 收藏

error code 0x80004005

记录一个小问题。
在Win7系统上装一个软件时失败,提示2个DLL没有注册成功。
于是准备手动注册。
运行
cd C:\WINDOWS\system32\
regsvr32 xxx.dll
后出现如下错误:
The module "xxx.dll" was loaded but the call to DllRegisterServer failed with error code 0x80004005.

网上搜索一番后,找到如下地址
http://forums.cnet.com/7723-12546_102-237219.html
其中有条说run as administrator,这是权限问题,不过我登陆的就是管理员账号,应该不存在这样的问题。

抱着姑且一试的想法,写了个cmd文件,右键run as administrator后,居然真的注册成功了!

看来Win7系统真的很安全,就算是管理员,也得来个run as administrator后才能做一些事,是在向sudo学习么?

posted @ 2011-12-06 21:13 李威 阅读(347) | 评论 (0)编辑 收藏

HTML5的audio标签很坑爹!

最近试着用html5在页面加载mp3文件。在chrome下测试通过了,偶然的用firefox4打开,居然没法用……
怀疑哪里写错了,可audio标签也就几个属性而已。

几经搜索,最后发现的真相让我很崩溃……firefox的audio不支持播放mp3。

Codec support in modern desktop browsers
Browser Ogg Vorbis MP3 WAV
FireFox 3.6+
Safari 5+
Chrome 6
Opera 10.5+
Internet Explorer 9 (beta)
出自 http://html5doctor.com/native-audio-in-the-browser/

看了这个表之后,虽然很多浏览器都支持html5,但如果你想播放一个文件,任何一种格式都不能让所有浏览器正常播放。
哈哈哈,html5定义了媒体标签,但没规定媒体的默认编码格式,导致各浏览器各自为政。
真是不方便……

posted @ 2011-06-11 22:30 李威 阅读(263) | 评论 (0)编辑 收藏

PHP GD画图时出现的文字乱码问题

GD画图时通常显示文字是用imagettftext方法,但它的参数必须是UTF-8编码的。
此时得注意php文件的编码
1.如果是UTF-8的,直接传硬编码字符串就可正常显示
2.如果是gb2312或其它的,则必须进行转换 mb_convert_encoding($str, 'UTF-8')

另外,还有一种情况,JIS-mapped Japanese Font Support被开启时,imagettftext就必须传SJIS编码,传UTF-8反而会乱码。
此时必须将其转码后传入,mb_convert_encoding($sStr,"SJIS", "UTF-8")。

以上。

posted @ 2011-03-31 15:46 李威 阅读(1041) | 评论 (0)编辑 收藏

TurboC3.0英文版中界面边框为乱码问题的解决发法

在次提供TurboC3.0英文版下载。

TCPP.rar
上网须谨慎,下载请杀毒。

TC3.0窗口模式,边框有中文乱码。全屏就没有。
原因是当前的code page是中文的936,可以在cmd中用chcp命令查看。
利用命令 chcp 437 改为老美的,就可以了。
具体操作
启动TCPP.exe->File->DOS Shell->chcp 437->exit
回到TCPP后就没乱码了。
但这个方法治标不治本,每次启动TCPP仍是乱码。

另一种方法
在TCPP窗口的左上角单击,出现菜单(包含最大化,最小化,属性等),在默认选项的第一个页面“选项”里Default code page选择437 (OEM United Status)。因为我目前使用的是英文系统,不知道中文系统中是否有该项。如果没有该项,请自行寻找方法让它有。
之后,一切OK,至少我OK了……

posted @ 2011-01-26 19:26 李威 阅读(700) | 评论 (0)编辑 收藏

运行李

中铁快运 跨省 4.3元/KG
一般3天到,但有时货运量大,无法确定到货时间
上午10:30电话过去,说下午2点后才能来取货,我说下午不在,比较紧急,实际上取货师傅11点多就到了
来取货的人有2人,开的是面包车,能一次运走较多货物
货物较散时会收15元包装费。
一般人不支持货到付款,只有大客户才支持。
先交费,多退少补(一般会多收),发票不当场发,之后会联系你或邮寄给送货地址(具体不详)。
我是当天要离开,没法将发票给我,他们说会将发票和多的钱放到包装的货物里。


顺丰快递 跨省 1KG内20元,超过部分12元/KG
到货很快,合肥到杭州一天内能送到。
来取货的只有1人,开电动车,货物较多时无法一次取完。
支持货到付款,无包装费。
客服说1小时内到,通常半小时左右会有取货人来电话联系,之后看情况,有时候半小时能到,有时候很拖。

posted @ 2011-01-15 11:31 李威 阅读(142) | 评论 (0)编辑 收藏

Sina App Enginge Beta

已经有人做了介绍
http://www.hzlzh.com/sina-app-engine-beta/

对我这种平时写点小应用自娱自乐的个人开发者来说,最重要的变化就是SAE不再免费了
1RMB=50云豆
SAE进入beta后发放给内测开发者5000云豆,我去帐号里查看时剩下4945,感觉用得有些快
平时也没写多少东西,也就10多个php页面,以后还是侧重玩GAE吧……

虽然SAE相比GAE规模不大,但也有些不错的地方
譬如cron,同样的5min间隔执行的东西,SAE比GAE更准些
譬如客户端,虽然SAE没法在本地执行代码,但能从服务器下载应用的最新代码很不错
之前GAE写的东西,有些是在公司电脑里写的,有些是在家里写的,现在都不知道家中电脑里的代码是不是最新的了
SAE进入beta后,能在线查看修改代码,使用的编辑器是ecoder,http://ecoder.quintalinda.com/

SAE很多其他功能还没用到,就不多做评价了

以下说点胡话吧
国内整体环境有些急功近利,运营1年多了,没任何收入,SAE也是国内第一个吃螃蟹的,能否盈利也不清楚,投资者沉不住气,SAE团队大概也是顶不住上层的压力,迫不得已开始收费计划。

总感觉SAE还没成熟到能收费的阶段,因为SAE上的应用并不多,我只见到10多个而已
应用能减少建站难度。应用少会限制SAE的用途,SAE面向的群体是什么呢,现在能干什么呢?个人的话,租php空间来干嘛,主要是搭博客,建论坛,搞CMS;想创业的,大概不会选SAE,因为限制太多,不如租主机,自由度更高;企业的话,注重的是稳定,现在还不会尝试新出来的SAE
开发SAE开源项目,SAE会奖励云豆。应用不多这点也能靠收费来激发开发者多发开些SAE开源项目来弥补,不知效果会如何

现在还真不知道SAE会发展得如何……

预计近期SAE应该会开发注册吧,新帐号里应该会有一些云豆,给开发者试用,然后期待这些新鲜血液带来更多付费用户和SAE开源项目,希望SAE能发展下去

posted @ 2010-09-05 12:28 李威 阅读(204) | 评论 (0)编辑 收藏

笑话一则(其中的我不是博主)

我出差的时候(是指在日本)
 张X(日本那边的人)说:“这个叫李X的代码写得真烂啊。”
我:“他是我室友。”过了一会
张X:“这个叫唐XX的写得更烂。”
我:“这个是我前室友。”再过了一会
张X很无奈地问我:“这个叫郑X一定是你的前前室友吧?”
我。。。

posted @ 2010-08-26 22:43 李威 阅读(147) | 评论 (0)编辑 收藏

如何破掉防盗链机制

今天遇到一个问题,写了一个页面,抓取其他某站点的内容,然后重组成新的页面,主要是一个图片的展示(gallery)。

但是该站点做了防盗链,图片无法显示,403.

这种盗链主要是靠Referer来实现的,也就是说更改了Referer就能显示图片,但Referer不是在页面编码能解决的。

Referer是浏览器发出的,只能更改浏览器才能更改Referer。

firefox有一个插件refcontrol,可以做到这一点,不过不是我要说的

继续研究,该站提供一种embed功能,供其他页面调用,此时就能允许其他站点直接显示图片。
一般网站是不提供这种功能的,所以下面方法并不是所有网站适用的。

通过对比header内容,最终知道是它在cookie里设定了一个字段,以此来判别。

那么,只要我设定该值即可。
两种方法
1.服务器端设定set-cookie,试验证明,此法不可行,主要是domain无法更改到对应站点的domain下
2.客户端用javascript设定document.cookie。仍不行……,原因不明,大概也是无法改domain吧

这下只剩最后一招了,在我的页面里直接调用embed页面,让它替我设cookie,如何调用呢?
首先想到用frame,试了下,frame和图片几乎同时发出request,这样cookie还没设定,请求图片肯定403.
又想到onload,呃,是在body完了后才调用,肯定不行
后来看到,html的head里的文件先下载完毕后,再请求图片。这点我以前也提到过,javascript代码的执行顺序 
head里主要有2种文件调用,js和css。
这里就不是什么正规写法了,因为embed页面既不是js文件,也不是css文件,但浏览器是不会管这个的,直接调用。
一般也不会这么用……旁门左道
先用了js这种,在src里写上embed页面地址,可以显示图片,但有个javascript错误。
接着改进,用css的,会发现最终调用了两次,一次是在开始,还有一次是在所有其他head文件全下载完之后
有些小影响,但问题不大。

时间比较晚,就懒得加上试验代码,OK,就这样,完工。

posted @ 2010-08-10 00:19 李威 阅读(837) | 评论 (0)编辑 收藏

javascript两则思考

1.
http://www.jsforest.org/2010/07/29/js-this指向的小测试/


这个说是在考this的指向,实际上是在考变量的作用域。
先说其中第二题。o是一个对象,doIt是它的方法,那么doIt的this自然指向o
第二题结果为10无悬念。

再来看第一题,在doIt的内部加入了一个setTimeout方法,setTimeout又调用了一个匿名方法。
在javascript中,函数(或方法)也是对象,那么匿名方法中的this应该指向doIt,结果为20.

实际上将代码跑了下,第一题结果为5.哪里错了?

问题出在setTimeout。
window.setTimeout(code, delay)
When code is executed, it is executed in the context of the Window object. If code is a function, the Window object is the value of the this keyword. If code is a string, it is evaluated in the global scope with the Window object as the only object on the scope chain. This is true even if the call to setTimeout( ) occurred within a function with a longer scope chain.

这段话说明了setTimeout不管在哪里执行,其作用域都是在Window下,this一直指向Window。
第一题的x=5是全局变量,Window作用域下的。

这题说是在考this的指向,原来最终考的是个setTimeout的问题……被耍了



2.
http://www.css88.com/archives/2429

看到这个问题,首先注意到的是第一个用了===,第二个没有,而javascript是个弱类型语言,使用provisionalTable[item]取值没判断类型。
然后,试着找了Object中判断值是否存在的方法,譬如provisionalTable.item ,in等都没判断类型。
想法一,重载[]方法,不过,这个怎么重载?又不是个function
想法二,数字是利用toString()转成字符串的,那么重载Number.prototype.toString=function(){return this;}; 6=='6'返回false了,但provisionalTable[item]取值还是一样
想法三,provisionalTable同时存在6和'6'时,provisionalTable[item]能区分这两者,那么在provisionalTable中加入一个设为true时,将另一个也加入,并设为false。但这样会有效率问题,事实上,acsu提出的方法里仅仅加了个typeof方法,就将效率损失殆尽。
突然想到,这个问题不是找解决方法,而是找最优方法
嗯,作罢,效率问题不是我等小民该考虑的,这个必须从根本上重构javascript才行

不过思考下,还是能学到很多东西的

posted @ 2010-08-05 22:07 李威 阅读(148) | 评论 (0)编辑 收藏

如何让博客支持PubSubHubbub

http://code.google.com/p/pubsubhubbub/ 
pubsubhubbub是google开发的一种Atom和RSS增强协议,能够接近实时发布信息。
也就是说,如果blogjava支持了pubsubhubbub,我在这里发布了博客,你就可以在你的阅读器里很快看到我的文章。
现在只有部分博客服务商提供了pubsubhubbub功能,譬如WordPress,FriendFeed,livedoor等。

pubsubhubbub的原理很简单。它由3部分组成,pub,sub,hub(最后的bub不是的,hubbub是骚动的意思)。
pub可以看成是博客,sub是阅读器,而hub是一个中转站。通常是由sub向pub请求内容,而pubsubhubbub是由sub想hub请求,hub再向pub请求,多一层hub的作用是降低pub的压力。hub收到pub的更新后,会向sub发布最新的内容。
因为不是pub直接向sub发布,所以这里说的“接近”实时发布信息。

那么如何让博客支持pubsubhubbub呢?只需要建立一个hub服务器,然后在生产rss时加入
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/>
http://pubsubhubbub.appspot.com就是hub服务器的地址。
<?xml version="1.0"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom">
  
<channel>
    
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/>
    
  
</channel>
</rss>
因此判断博客是否正常pubsubhubbub,也很简单,查看http://www.blogjava.net/liwei/rss的代码即可,没有hub的影子。
再看一个支持的例子 http://rasjacobson.wordpress.com/feed/ ,里面有一句 <atom:link rel='hub' href='http://rasjacobson.wordpress.com/?pushpress=hub'/> ,这个是支持的。

具体的hub实现请查看
http://code.google.com/p/pubsubhubbub/wiki/Hubs
我这里只是个人玩玩而已,没实力自己搭hub服务器。不过可以借助他人提供的hub服务器,譬如刚才appspot的。

知道了原理,接下来就好办。
因为要改代码才能修改生产的RSS,所以blogjava这种博客服务商不提供pubsubhubbub功能的话,我们这些用户是无能为力的。

但自建的独立博客是能简单支持。等咱啥时候有闲钱了,再去做吧……

posted @ 2010-08-01 01:35 李威 阅读(293) | 评论 (0)编辑 收藏