李威 さぽている

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

2010年3月11日 #

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)编辑 收藏

GAE发布时出现的SSL问题

deploy时会出现如下信息

WARNING appengine_rpc.py:399 ssl module not found. 
Without the ssl module, the identity of the remote host cannot be verified, and 
connections may NOT be secure. To fix 
this, please install the ssl module from 
http:
//pypi.python.org/pypi/ssl . 
To learn more, see http://code.google.com/appengine/kb/general.html#rpcssl 

当打开上面的页面时会自动转到 http://code.google.com/intl/zh-CN/appengine/kb/general.html#rpcssl ,在这里看不到任何帮助,因为google还没将这段帮助信息翻译成中文Orz,可以到 http://code.google.com/intl/en/appengine/kb/general.html#rpcssl 查看。这里说明在用python appcfg.py update 命令时添加 --insecure 后就不会有问题。但我用GAE Launcher也无法修改命令。再让我回到没有Launcher,直接用命令行的时代,还真难适应。作罢。

我试着安装了ssl 模块,但无法编译。网上找到了这个页面,http://canofy.javaeye.com/blog/651968 ,该同学和我遇到了同样的问题,并且装了cygwin。
貌似之后还有其他问题。不谈。

今天,我突然发现,deploy时出现的ssl信息,完全可以忽视,对,可以忽视 ,之后仍会update成功的。
通常出现上述ssl提示后,console会没有任何显示,此时不要关闭console,再次deploy时会出现如下信息
Error 409--- begin server output ---
Another transaction by user xxxxxx is already in progress 
for this app and major version. That user can undo the transaction with appcfg.py's "rollback" command.
--- end server output ---
这表明之前的update仍在进行。请安心等待……

最后,好嘛,一个不是问题的问题,花了我不少时间……

posted @ 2010-05-08 12:25 李威 阅读(746) | 评论 (1)编辑 收藏

javascript代码的执行顺序

这个不弄明白,代码出问题了也不难以解决。
《learning Jquery 1.3》p15有一句  JavaScript code is generally run as soon as it is encountered in the browser
也就是说,浏览器遇到一个语句就立刻解析。貌似这个问题很快就解决了。

但javascript的写法相当多,譬如网上很多人讨论的$(document).ready(和<body onload= 执行先后问题
在p16中,提到onload    to run after the page is completely loaded.即onload在页面完全加载完之后执行
ready是firing once the DOM is loaded—without waiting for images 。ready在DOM加载完,图片未加载时执行。
也即ready在onload之前调用。

这里就涉及html页面的加载顺序问题。网上搜到2篇相关文章。
浏览器做了什么?
http://www.cnblogs.com/guilipan/archive/2010/01/06/1640145.html
Javascript在页面加载时的执行顺序
http://dancewithnet.com/2007/03/22/order-of-execution-of-javascript-on-web/

看完之后,比之前明白了些,但具体的关系还是没能理解。
一个html页面包括head和body两个部分,head部会调用外部CSS和JS文件,body部会调用图片,音视频等内容。
下载顺序是html ->CSS JS ->图片等。
解析顺序是html(内部是按序执行head->body)->DOM生成 ->ready执行 ->图片下载 ->body.onload

将以上两者结合,html ->head(CSS JS) ->body->DOM生成 ->ready执行 ->图片下载 ->body.onload
其中head和body部都可能包含js,按代码顺序执行。
这里就有一个疑问,浏览器会等待JS等文件下载完后,并顺序执行该JS后再继续执行之后的html代码么?
按想应该不会,不然JS文件过大,会影响html页面渲染的速度,两者应该是异步的。
但这个异步就会将之前总结的顺序搅乱。譬如onload都执行完了,包含ready的JS还没下完,此时会发生什么?
这里说得有问题,JS未下载完,onload是不会执行的。
有待继续总结……

posted @ 2010-03-11 00:18 李威 阅读(467) | 评论 (0)编辑 收藏