国庆前(2013)无聊,就在铁道部的12306上“逛”了下下。

PS:原来之所以叫12306,是因为其客服号码是12306,好吧,我很无知……

首先是被“逛”的页面:票价查询

之所以去逛,是因为一直听闻该网站在节假日期间抢票慢、难,而国内浏览器厂商等开发抢票插件等等,这让我有些心动,于是便去瞧了瞧“传说”中的12306。

对于该页面的第一反应是,功能应该可以的,不然大家抢不到票了,不过美观的角度就不怎么样了。

本以为该页面会是用Ajax方式提及获取数据(因点查询后页面并无刷新迹象,且余票查询是Ajax请求方式的),于是通过Firebug观察提交的方式及返回的内容,发现是以POST方式的表单提交,而返回的内容居然是如下形式的代码:

<script>
parent.document.getElementById("randCode").value="";
parent.document.getElementById("img_rrand_code").src="passCodeActi0n.do?rand=rrand"+'?'+Math.random(); parent.document.getElementById("stationDIV").innerHTML="<strong>北京</strong>→<strong>上海</strong>列车票价信息暂无";
parent.document.getElementById("stationDIV2").innerHTML="<strong>上海</strong>→<strong>北京</strong>列车票价信息暂无";
<!-- =====================================================返程========================================================== -->
parent.document.getElementById("stationDIV2").style.display='none';
parent.document.getElementById("gridbox2").style.display='none';
</script>

返回的这个信息让人非常不解,一般POST提交都是会“跳转”页面的,而这里返回了似乎是html代码的script标签,内部是含有返回数据的js代码。(代码和数据这两家伙,这么亲密-_-!)

对此我有两个疑问:

1)表单提交返回了这个代码,但是页面怎么没刷新呢?

2)很明显返回的代码起了作用,因为查询结果出现在了页面上,咋回事?

细心的人可能注意到了上面的代码中一个明显的地方(我表示当时我没注意这个-.-),即parent.document字样,这个是在iframe嵌套时,调用父iframe中window的操作,明显这里有蹊跷,当前页面提交后,返回的代码中居然是通过parent.document字样的js代码来操作页面的。

另外,页面中表单标签的代码如下:

<form action="iframeTicketPriceByStation.jsp"
method="post" name="ticketPriceByStationform"
target="iframeName1">
<!-- 此处略去x行代码 -->
</form>

这里的target属性让我感到可疑,特别是搜索target的值“iframeName1”后,在页面中有如下iframe代码,该iframe隐藏了:

<iframe name="iframeName1" id="iframeID1" src="" width="0" height="0"
frameborder="0" />

初步猜测表单提交后返回的页面加载到该iframe中了,对form的target做些调查后便能确定下来了。

查询w3school上的介绍:target 属性规定在何处打开 action URL。

不过对于该属性的使用上却有些“兼容性”的问题:

在 HTML 4.01 中,不赞成使用 form 元素的 target 属性;在 XHTML 1.0 Strict DTD 中,不支持该属性。(链接

在 HTML5 中 target 属性不再是被废弃的属性。(链接

通过查看XHTML 1.0 Strict DTD对form的定义,已经没有target属性了:

<!ATTLIST form
%attrs;
action %URI; #REQUIRED
method (get|post) "get"
enctype %ContentType; "application/x-www-form-urlencoded"
onsubmit %Script; #IMPLIED
onreset %Script; #IMPLIED
accept %ContentTypes; #IMPLIED
accept-charset %Charsets; #IMPLIED
>

但在XHTML 1.0 Transitional DTD中还保留着:

<!ATTLIST form
%attrs;
action %URI; #REQUIRED
method (get|post) "get"
name NMTOKEN #IMPLIED
enctype %ContentType; "application/x-www-form-urlencoded"
onsubmit %Script; #IMPLIED
onreset %Script; #IMPLIED
accept %ContentTypes; #IMPLIED
accept-charset %Charsets; #IMPLIED
target %FrameTarget; #IMPLIED
>

看来该属性一度有被遗弃的现象,虽然在HTML5中已能正常使用了,但对于该属性的使用我还是不怎么习惯,总觉得有些另类哈……

以上介绍已经明了,该属性指定在何处打开表单提交的url,按照我们平时的使用可推测,默认情况是在当前页面。

参考对Target属性的介绍,它可以有如下值,这些值应该是很熟悉的了,涉及到链接的时候,都会有这几个出现:

描述
_blank 在新窗口/选项卡中打开。
_self 在同一框架中打开。(默认)
_parent 在父框架中打开。
_top 在整个窗口中打开。
framename 在指定的框架中打开。

很明显,票价查询页面上用的是framename这类型的值,起初在看该页面中的iframe标签属性是还让人有点迷糊,因为这里给iframe加了相同的id和name,这是一种习惯,但也让人疑惑target中放入的到底是id还是name?

以下是我的测试代码:

1)主页面:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>The Target of Form</title>
</head> <body>
<form action="js.html" method="post" target="iframeName1">
<input type="submit" value="test1" />
</form>
<iframe name="iframeName1" id="iframeID1" src="" width="0" height="0" frameborder="0" >
</iframe> <form action="js.html" method="post" target="iframeName2"> <!-- 指定name,如果不存在,这个name作为新开窗口的window.name -->
<input type="submit" value="test2" />
</form>
<iframe id="iframeID2" src="" width="0" height="0" frameborder="0" >
</iframe>
</body>
</html>

2)表单提交的页面(虽然可以只写script标签的代码就行了,但总觉得不规范……):

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>The Target of Form</title>
<script>
alert(123);
</script>
</head>
<body>
</body>
</html>

PS: 当target指定的name不存在时(这个涉及到window.name属性了),那么会新开一个window.name为该name值的窗口。之后的每次提交都会到这个窗口来,如果关闭了此窗口,那么再次提交时还是会新开启窗口的。

PPS: 关于重复表单提交(点击刷新按钮),似乎对于新开窗口方式,无重复提交现象出现(感觉这种方式就是以POST形式新开窗口-_-)。而针对内嵌的iframe方式,则会有重复表单提交现象(IE8、Firefox如此,但Chrome除外),具体如何我就不进行测试了,这是题外话了,问题无处不在,有新的东西就有新的问题,有兴趣的朋友自己试试。

最后吐槽下,该页面http://dynamic.12306.cn/map_zwdcx/CCCX.jsp的验证码是js生成的数字,不禁让我回想起去年写过的类似代码,只是这里的代码兼容性真是差呢,也就ie下能运行了。

参考资料:

  http://www.12306.cn/mormhweb/tlkytst/

  http://zhidao.baidu.com/link?url=ER04KXHiSYmxCZ7ptQCbFYIDIpUFPlcG35xSVHxX-YchSYT4Mi7uU8jeeJsnhbg4ckm_W310ePpa-TC5y6G9Na

  http://www.w3school.com.cn/tags/att_form_target.asp

  http://www.w3school.com.cn/html5/att_form_target.asp

  http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd

  http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd

话说Form标签的target属性-----无刷新表单提交的更多相关文章

  1. DWZ框架Ajax无刷新表单提交处理流程

    DWZ框架Ajax无刷新表单提交处理流程是: 1.       ajax表单提交给服务器 2.       服务器返回一个固定格式json结构 3.       js会调函数根据这个json数据做相应 ...

  2. js实现无刷新表单提交文件,将ajax请求转换为form请求方法

    最近在做项目的时候遇到一个需要上传文件的需求,因为ajax请求是无法上传二进制文件流的,所以只能用form表单提交,而form提交有一个问题就是会使页面刷新,本文解决了form表单提交文件时页面刷新的 ...

  3. ajax+FormData+javascript实现无刷新表单信息提交

    ajax+FormData+javascript实现无刷新表单信息提交 原理: dom收集表单信息,利用FormData快速收集表单信息  ,实例化表单数据对象 同时收集fm的表单域信息. var f ...

  4. ajax+FormData+javascript 实现无刷新表单注册

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  5. 使用jquery form插件进行异步带文件的表单提交

    引入form插件与jquery 的js文件后 获取表单的jq对象 然后.ajaxSubmit提交表单即可 实现添加品牌的异步表单提交 function addBarandImg(formId) { $ ...

  6. a标签指定的url,在表单提交前进行js验证的实现

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  7. Ajax 使用formdata 实现 无刷新表单上传

    FormData对象的作用就类似于这里的serialize()方法,不过FormData是浏览器原生的,且支持二进制文件 1.这里实现一个无刷新上传图片,成功后页面显示 点击button 触发隐藏的 ...

  8. HTML <form> 标签的 method 属性(20161028)

    HTML <form> 标签的 method 属性 HTML <form> 标签 实例 在下面的例子中,表单数据将通过 method 属性附加到 URL 上: <form ...

  9. form表单提交target属性使用

    通过form表单提交刷新iframe <form action="doctor/selPackage" target="projectlistframe" ...

随机推荐

  1. 解决ubuntu中firefox浏览器总是提示找不到server的问题

    这个情况在我机器上常常出现,并且时不时的给你出点问题.可是有些时候等一下就好了.或者把引擎换到百度的话它就又行得通了.. 被这个问题搞得非常烦.上网查了下说是防火墙啊之类的出问题.可是自己弄了后这个问 ...

  2. python js

    js = 'var a=document.getElementsByClassName("user-data-right")[0];a.target="_self&quo ...

  3. 【OI新闻】2016.10.26 - NOIP初赛泄题再次引爆

    有点劲,开车注意点,小心翻啦~ http://www.noi.cn/noi-news/noi/743-ccfnoip2016 CCF在NOIP2016初赛结束后接到举报:初赛前(22日12时左右),网 ...

  4. HDU 4850 Wow! Such String!

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4850 题意:给定一个N(1 ≤ N ≤ 500000),构造一个长度为N的小写字母字符串,要求所有长度大于 ...

  5. leetcode 784. Letter Case Permutation——所有BFS和DFS的题目本质上都可以抽象为tree,这样方便你写代码

    Given a string S, we can transform every letter individually to be lowercase or uppercase to create ...

  6. flask g对象

    g对象  一次请求中使用 下面用redirect重定向,不是同一次请求了 g:global 1. g对象是专门用来保存用户的数据的. 2. g对象在一次请求中的所有的代码的地方,都是可以使用的. 使用 ...

  7. 利用XStream实现对象XML话

    使用Java原生的序列化的方式来表示一个对象.总结一下这种对象表示方式的优缺点: 1.纯粹的Java环境下这种方式可以很好地工作,因为它是Java自带的,也不需要第三方的Jar包的支持 2.多语言环境 ...

  8. Tomcat启动Web.xml引用其它XML配置报FileNotFound异常解决方案

    如果使用JEECG框架进行Tomcat启动时,如果web.xml引用了其他xml文件,需要在tomcat文件夹里的config文件夹里的context.xml文件里的Context标签里配置xmlBl ...

  9. Django day 38 结算中心,支付中心,计算价格方法

    一:结算中心 二:支付中心 三:计算价格方法

  10. object-c中实现特定一个或者多个页面横竖屏,其他界面保持竖屏显示。

    1.首先设置项目支持的屏幕方向.info.plist设置(自行设置) 2.写一个子类CusNavigationController 继承 UINavigationController,在CusNavi ...