背景
异步跨域请求时JSONP方式是最靠谱的选择,常规的,被请求页面应该返回诸如此类的数据格式:
handleName="xxx";doSomething();...;
需要时,我们还可以返回其他的JS语句,只要符合语法即可。
- – - – - – -分割线- – - – - – -
最近我做了一个任务,要把后台生成的HTML模板文件改造成JSONP的形式输出,供前端异步调用。
模板文件大致这样的格式:
<div class="xxx">
<h3>something</h3>
<div class="xxx">
she's
beautiful
</div>
</div>
制约条件:模板页面我不能动,因为它还需要被其他模板页面引用
分析
由于受到制约不能更改模板页面的内容,将其改造成JSONP形式很有难度,新建一个页面进行组织必不可少,我起初把步骤分为:
- 新建页面(php)
- 引入模板页面 @include
- 用单引号包含之
- 在其头部加上handleName = ,在其后加上分号结束
- 输出
php代码:
handleName = '<?php @include_once("filePath") ?>';
实际操作中遇到了麻烦,原因是模板内容都是换行的,最后组织好的内容成了这样:
handleName = '<div class="xxx">
<h3>something</h3>
<div class="xxx">
she's
beautiful
</div>
</div>';
- 赋值表达式换行在JS里是不合语法的!
- she’s的单引号更是扰乱了这个赋值表达式…
格式化来源文件势在必行!
…
file_get_contents, javascript, jsonp, PHP, readfile, 格式化
一、容易被忽略的局部变量
var a = 5;
(function(){
alert(a);
var a = a ++;
alert(a);
})()
alert(a);
思考这段代码的执行结果。
执行后,看看是否和你想象的一致?
ok,这段代码里核心的知识点是 var a = a++,其中两个变量 a 都是匿名函数内部的局部变量,是同一个,和全局变量 a 是不一样的。
为什么?我们来看看ECMA规范对变量声明语句的定义:
Description
If the variable statement occurs inside a FunctionDeclaration, the
variables are defined with function-local scope in that function, as
described in s10.1.3. Otherwise, they are defined with global scope
(that is, they are created as members of the global object, as described
in 10.1.3) using property attributes { DontDelete }. Variables are
created when the execution scope is entered. A Block does not define a new
execution scope. Only Program and FunctionDeclaration produce a new
scope. Variables are initialised to undefined when created. A variable with
an Initialiser is assigned the value of its AssignmentExpression when the
VariableStatement is executed, not when the variable is created.
声明中提到:进入作用域环境后,变量就会被创建,并赋予初始值undefined。在变量声明语句执行时才会把赋值表达式的值指派给该变量,而并不是在该变量被创建时。
因此上面的代码可以等价于…
ECMA, javascript, 全局, 变量, 局部, 特性
问题及背景
今天项目组的开发同学急冲冲地叫上我看一个他写的JS脚本,好端端的一个form提交时参数无法正常传递。代码是这样的
<form method="get" name="xxx" id="xxx" action="uri?xxx=xxx&yyy=yyy" >
<input name="zzz" type="text" value="zzz" />
<input id="submit" type="button" value="提交" />
</form>
<script>
document.getElementById('submit').onclick = function(){
var form = document.xxx;
form.action = form.action +
(form.action.indexOf('?') > -1 ? '&' : '?') + form.zzz.value;
form.submit();
}
</script>
其本意是在提交是要同时提交xxx、yyy、zzz三个参数,但最终提交的参数只有zzz,即uri只是 uri?zzz=zzz。
分析
这是为什么呢?脚本没有问题呀,感觉方法也没什么问题,在调试了多次无果之后,我把注意点移到了form本身:在禁用了脚本之后,form同样只提交了zzz参数。
最后,终于知道原因是form使用了get方法。
HTML 4.01 specification 的解释
If the method is "get" - -, the user agent takes the value of action,
appends a ? to it, then appends the form data set,
encoded using the application/x-www-form-urlencoded content type.
The user agent then traverses the link to this URI. In this scenario,
form data are restricted to ASCII codes.
get方式是method的默认值,其方式是将form表单中的数据集值对组织到action中的uri之后,不过其组织方式是有讲究的:
- uri在submit最后才进行组织
- 在添加’?'时,uri中额外参数会被舍弃,接着只拼接表单内的域值
- uri hash值会被保留:uri?xxx=xxx#here,#here会被保留
form, get, post, uri
前日对iframe的几种文档对象获取方式做了测试,发现一些有趣现象,与大家分享!
假设在页面嵌入如下iframe:
<iframe id="testFrame" name="testFrame" src="#" frameborder="0" border="0" scrolling="no" style="display:none"></iframe>
众所周知,iframe是内嵌窗口,我们可以通过多种方式获取iframe对象及其window\document对象(同域前提),不过哪些是哪些有时会搞不清,测试目的也是为了加深记忆。
比较常见的方法有以下几种,分别测试:
- A:document.getElementById(‘testFrame’)
- B:window.frames['testFrame'];
- C:document.getElementById(‘testFrame’).contentWindow
测试结果(非IE浏览器及IE8)

从测试结果及其比对结果可以看出,A得到的是iframe这个html标签对象,B和C得到的是iframe浏览器对象(window),有意思的是IE7及以下版本浏览器认为这两者是不恒等的
…
document, dom, iframe, window, 兼容
Javascript开发中,需要与0,undefined,null,false进行等同比较时,我们知道,用’===’(恒等)比较靠谱,我是在第一次使用jslint时知道这点的,例如在Jslint中验证
var test = '';
alert(test==0);
会得到提示:
Use '===' to compare with '0'
看看ECMA规范中是如何对==和===操作符进行定义的,了解其深层的规则以及jslint提示的缘由
首先介绍==
11.9.1 等同运算符( == )
运算符规则如下所示:
1. 计算运算符左侧表达式;
2. 对第1步的结果调用GetValue;
3. 计算运算符右侧表达式;
4. 对第1步的结果调用GetValue;
5. 对第4步的结果与第2步结果执行比对(参考 11.9.3);
6. 返回第5步结果;
再来详细了解比对过程(11.9.3)
11.9.3 抽象的等同比对算法…
ECMA, equals, identical, javascirpt, strict, 恒等, 操作符, 等同, 规范
dean.edwards在被问及“不写代码的时候都在干些什么?”时非常囧地答道:“在测试和修bug(testing&debugging)”,这便是开发工程师共同的命运=.=! 我们整天都在编码、测试、Debug,忙的不亦乐乎。不过还好,有很多现成工具可以帮助我们更容易更快速地定位页面内的脚本问题,抽空还能偷个懒,简单搞个例子,看看它们是如何帮助我们的…
fiddler, firebug, javascript, location
通常我们用 js 脚本创建 iframe 时,会这样写:
var iframe = document.createElement('iframe');
之后我们可能会定义 id、name、border 等属性,这些看似简单,其实 IE 与非 IE 浏览器之间、IE 和 IE 高版本之间的迥异,使得 iframe 的相关兼容性操作非常地有文章…
frameborder, iframe, name, onload, target
全中国都是墙,偶懒的翻,因此经常看老外 Twitter 发的短地址就比较杯具,于是用longurlplease提供的 API 做的短地址还原小应用,主要是自己用着好用,支持批量还原,当然今后还可以做成浏览器插件。话说 longurlplease 提供的 API 还真的很全面,一定要顶个,还有 Flash Air ,有空再整。
呃,很简单的东西就不多讲了,直接狂点此链接试用。
OK,继续加班 =.=!
呃,再加个图,增加些点击欲望……


longurlplease, real url, short url, 短地址
题目不知道如何去归纳了,总之本文的重点在后面,this关键字在函数调用模式时为何会绑定到全局变量,答案真的在后面^_^
apply, call, function, javascript, this
一、函数表达式与函数声明
/*函数表达式*/
var test = function(){
console.debug('hello world');
}
/*函数声明*/
function test(){
console.debug('hello world');
}
两种方式并不是一致的,看下面的比较代码
test();//不会被执行,因为虽然test已经声明是一个变量,但还未被赋予任何类型的值
var test = function(){
do something
}
constructor, function, javascript, object