国庆前(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. [办公自动化]如何将PPT转为PDF,免费

    同事需要把PPT格式的文档转为PDF.她没有安装adobe acrobat,安装了微软office 2007. 这个其实可以通过安装微软官方插件来解决.无需额外费用. 所需软件为: 2007 Micr ...

  2. 蓝桥 ADV-230 算法提高 12-1三角形 【数学公式】

      算法提高 12-1三角形   时间限制:1.0s   内存限制:256.0MB      问题描述 为二维空间中的点设计一个结构体,在此基础上为三角形设计一个结构体.分别设计独立的函数计算三角形的 ...

  3. POJ2115 C-Loop

    传送门 这道题是求解不定方程的一道好练习题. 题目描述的很诡异……还说什么k进制,其实就是要求一个数A,每次加C,问到B要加多少次,所有的数对2k取模. 也就是说我们能列出如下方程:A+xC ≡ B ...

  4. linux下的C语言开发(定时器)

    定时器是我们需要经常处理的一种资源.那Linux下面的定时器又是怎么一回事呢?其实,在linux里面有一种进程中信息传递的方法,那就是信号.这里的定时器就相当于系统每隔一段时间给进程发一个定时信号,我 ...

  5. openStack集群封装记录

  6. 287 Find the Duplicate Number 寻找重复数

    一个长度为 n + 1 的整形数组,其中的数字都在 1 到 n 之间,包括 1 和 n ,可知至少有一个重复的数字存在.假设只有一个数字重复,找出这个重复的数字.注意:    不能更改数组内容(假设数 ...

  7. 设计基于HTML5的APP登录功能及安全调用接口的方式

    转自:http://blog.csdn.net/linlzk/article/details/45536065 最近发现群内大伙对用Hbuilder做的APP怎么做登录功能以及维护登录状态非常困惑,而 ...

  8. Java 8 (3) Stream 流 - 简介

    什么是流? 流是Java API的新成员,它允许你以声明性方式处理数据集合(通过查询语言来表达,而不是临时编写一个实现).就现在来说你可以先把它当做是一个遍历数据集的高级迭代器.此外,流还支持并行,你 ...

  9. Java多线程——线程之间的协作

    Java多线程——线程之间的协作 摘要:本文主要学习多线程之间是如何协作的,以及如何使用wait()方法与notify()/notifyAll()方法. 部分内容来自以下博客: https://www ...

  10. Python学习日记之练习代码

    # -*- coding:utf-8 -*- number = 23 test=True while test: guess=int(raw_input('输入数字')) if guess==numb ...