`

Ajax漫步(三)用XMLHttpRequest 发送请求

    博客分类:
  • Ajax
阅读更多

用 XMLHttpRequest 发送请求

得到请求对象之后就可以进入请求/响应循环了。记住,XMLHttpRequest 惟一的目的是让您发送请求和接收响应。其他一切都是 JavaScript、CSS 或页面中其他代码的工作:改变用户界面、切换图像、解释服务器返回的数据。准备好 XMLHttpRequest 之后,就可以向服务器发送请求了。

欢迎使用沙箱

Ajax 采用一种沙箱安全模型。因此,Ajax 代码(具体来说就是 XMLHttpRequest 对象)只能对所在的同一个域发送请求。以后的文章中将进一步介绍安全和 Ajax,现在只要知道在本地机器上运行的代码只能对本地机器上的服务器端脚本发送请求。如果让 Ajax 代码在 www.breakneckpizza.com 上运行,则必须 www.breakneck.com 中运行的脚本发送请求。

设置服务器 URL

首先要确定连接的服务器的 URL。这并不是 Ajax 的特殊要求,但仍然是建立连接所必需的,显然现在您应该知道如何构造 URL 了。多数应用程序中都会结合一些静态数据和用户处理的表单中的数据来构造该 URL。比如,清单 7 中的 JavaScript 代码获取电话号码字段的值并用其构造 URL。

清单 7. 建立请求 URL

 <script language="javascript" type="text/javascript">
   var request = false;
   try {
     request = new XMLHttpRequest();
   } catch (trymicrosoft) {
     try {
       request = new ActiveXObject("Msxml2.XMLHTTP");
     } catch (othermicrosoft) {
       try {
         request = new ActiveXObject("Microsoft.XMLHTTP");
       } catch (failed) {
         request = false;
       } 
     }
   }
   if (!request)
     alert("Error initializing XMLHttpRequest!");
   function getCustomerInfo() {
     var phone = document.getElementById("phone").value;
     var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
   }
</script>

这里没有难懂的地方。首先,代码创建了一个新变量 phone,并把 ID 为 “phone” 的表单字段的值赋给它。清单 8 展示了这个表单的 XHTML,其中可以看到 phone 字段及其 id 属性。

清单 8. Break Neck Pizza 表单
<body>
  <p><img src="breakneck-logo_4c.gif" alt="Break Neck Pizza" /></p>
  <form action="POST">
   <p>Enter your phone number:
    <input type="text" size="14" name="phone" id="phone"
           onChange="getCustomerInfo();" />
   </p>
   <p>Your order will be delivered to:</p>
   <div id="address"></div>
   <p>Type your order in here:</p>
   <p><textarea name="order" rows="6" cols="50" id="order"></textarea></p>
   <p><input type="submit" value="Order Pizza" id="submit" /></p>
  </form>
 </body>

还要注意,当用户输入电话号码或者改变电话号码时,将触发 清单 8 所示的 getCustomerInfo() 方法。该方法取得电话号码并构造存储在 url 变量中的 URL 字符串。记住,由于 Ajax 代码是沙箱型的,因而只能连接到同一个域,实际上 URL 中不需要域名。该例中的脚本名为 /cgi-local/lookupCustomer.php。最后,电话号码作为 GET 参数附加到该脚本中:"phone=" + escape(phone)

如果以前没用见过 escape() 方法,它用于转义不能用明文正确发送的任何字符。比如,电话号码中的空格将被转换成字符 %20,从而能够在 URL 中传递这些字符。

可以根据需要添加任意多个参数。比如,如果需要增加另一个参数,只需要将其附加到 URL 中并用 “与”(&)字符分开 [第一个参数用问号(?)和脚本名分开]。

打开请求

open() 是打开吗?
Internet 开发人员对 open() 方法到底做什么没有达成一致。但它实际上并不是 打开一个请求。如果监控 XHTML/Ajax 页面及其连接脚本之间的网络和数据传递,当调用 open() 方法时将看不到任何通信。不清楚为何选用了这个名字,但显然不是一个好的选择。

有了要连接的 URL 后就可以配置请求了。可以用 XMLHttpRequest 对象的 open() 方法来完成。该方法有五个参数:

  • request-type:发送请求的类型。典型的值是 GETPOST,但也可以发送 HEAD 请求。
  • url:要连接的 URL。
  • asynch:如果希望使用异步连接则为 true,否则为 false。该参数是可选的,默认为 true。
  • username:如果需要身份验证,则可以在此指定用户名。该可选参数没有默认值。
  • password:如果需要身份验证,则可以在此指定口令。该可选参数没有默认值。

通常使用其中的前三个参数。事实上,即使需要异步连接,也应该指定第三个参数为 “true”。这是默认值,但坚持明确指定请求是异步的还是同步的更容易理解。

将这些结合起来,通常会得到 清单 9 所示的一行代码。

   function getCustomerInfo() {
     var phone = document.getElementById("phone").value;
     var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
     request.open("GET", url, true);

挑战异步性

本系列的后面一篇文章中,我将用很多时间编写和使用异步代码,但是您应该明白为什么 open() 的最后一个参数这么重要。在一般的请求/响应模型中,比如 Web 1.0,客户机(浏览器或者本地机器上运行的代码)向服务器发出请求。该请求是同步的,换句话说,客户机等待服务器的响应。当客户机等待的时候,至少会用某种形式通知您在等待:

  • 沙漏(特别是 Windows 上)。
  • 旋转的皮球(通常在 Mac 机器上)。
  • 应用程序基本上冻结了,然后过一段时间光标变化了。

这正是 Web 应用程序让人感到笨拙或缓慢的原因 —— 缺乏真正的交互性。按下按钮时,应用程序实际上变得不能使用,直到刚刚触发的请求得到响应。如果请求需要大量服务器处理,那么等待的时间可能很长(至少在这个多处理器、DSL 没有等待的世界中是如此)。

而异步请求 等待服务器响应。发送请求后应用程序继续运行。用户仍然可以在 Web 表单中输入数据,甚至离开表单。没有旋转的皮球或者沙漏,应用程序也没有明显的冻结。服务器悄悄地响应请求,完成后告诉原来的请求者工作已经结束(具体的办法很快就会看到)。结果是,应用程序感觉 那么迟钝或者缓慢,而是响应迅速、交互性强,感觉快多了。这仅仅是 Web 2.0 的一部分,但它是很重要的一部分。所有老套的 GUI 组件和 Web 设计范型都不能克服缓慢、同步的请求/响应模型。

发送请求

一旦用 open() 配置好之后,就可以发送请求了。幸运的是,发送请求的方法的名称要比 open() 适当,它就是 send()

send() 只有一个参数,就是要发送的内容。但是在考虑这个方法之前,回想一下前面已经通过 URL 本身发送过数据了:

var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);

虽然可以使用 send() 发送数据,但也能通过 URL 本身发送数据。事实上,GET 请求(在典型的 Ajax 应用中大约占 80%)中,用 URL 发送数据要容易得多。如果需要发送安全信息或 XML,可能要考虑使用 send() 发送内容(本系列的后续文章中将讨论安全数据和 XML 消息)。如果不需要通过 send() 传递数据,则只要传递 null 作为该方法的参数即可。因此您会发现在本文中的例子中只需要这样发送请求(参见 清单 10)。

function getCustomerInfo() {
     var phone = document.getElementById("phone").value;
     var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
     request.open("GET", url, true);
     request.send(null);
   }

指定回调方法

现在我们所做的只有很少一点是新的、革命性的或异步的。必须承认,open() 方法中 “true” 这个小小的关键字建立了异步请求。但是除此之外,这些代码与用 Java servlet 及 JSP、PHP 或 Perl 编程没有什么两样。那么 Ajax 和 Web 2.0 最大的秘密是什么呢?秘密就在于 XMLHttpRequest 的一个简单属性 onreadystatechange

首先一定要理解这些代码中的流程(如果需要请回顾 清单 10)。建立其请求然后发出请求。此外,因为是异步请求,所以 JavaScript 方法(例子中的 getCustomerInfo())不会等待服务器。因此代码将继续执行,就是说,将退出该方法而把控制返回给表单。用户可以继续输入信息,应用程序不会等待服务器。

这就提出了一个有趣的问题:服务器完成了请求之后会发生什么?答案是什么也不发生,至少对现在的代码而言如此!显然这样不行,因此服务器在完成通过 XMLHttpRequest 发送给它的请求处理之后需要某种指示说明怎么做。

在 JavaScript 中引用函数
JavaScript 是一种弱类型的语言,可以用变量引用任何东西。因此如果声明了一个函数 updatePage(),JavaScript 也将该函数名看作是一个变量。换句话说,可用变量名 updatePage 在代码中引用函数。

现在 onreadystatechange 属性该登场了。该属性允许指定一个回调函数。回调允许服务器(猜得到吗?)反向调用 Web 页面中的代码。它也给了服务器一定程度的控制权,当服务器完成请求之后,会查看 XMLHttpRequest 对象,特别是 onreadystatechange 属性。然后调用该属性指定的任何方法。之所以称为回调是因为服务器向网页发起调用,无论网页本身在做什么。比方说,可能在用户坐在椅子上手没有碰键盘的时候调用该方法,但是也可能在用户输入、移动鼠标、滚动屏幕或者点击按钮时调用该方法。它并不关心用户在做什么。

这就是称之为异步的原因:用户在一层上操作表单,而在另一层上服务器响应请求并触发 onreadystatechange 属性指定的回调方法。因此需要像 清单 11 一样在代码中指定该方法。

清单 11. 设置回调方法

 function getCustomerInfo() {
     var phone = document.getElementById("phone").value;
     var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
     request.open("GET", url, true);
     request.onreadystatechange = updatePage;
     request.send(null);
   }

需要特别注意的是该属性在代码中设置的位置 —— 它是在调用 send() 之前 设置的。发送请求之前必须设置该属性,这样服务器在回答完成请求之后才能查看该属性。现在剩下的就只有编写 updatePage() 方法了,这是本文最后一节要讨论的重点。

                                                                        

分享到:
评论

相关推荐

    ajax页面数据自动保存

    3. **发送请求**:通过`send()`方法发送请求。如果是POST请求,需要将数据作为参数传递。 ```javascript xhr.send(formData); ``` 4. **监听状态变化**:使用`onreadystatechange`事件监听请求状态变化,当`...

    tranquil-spaces:宁静的空间漫步在 SBU

    JavaScript 可以处理事件(如点击按钮)、操作DOM(文档对象模型,用于访问和修改网页内容)、发送Ajax请求(异步数据交换,使得网页可以在不刷新的情况下更新内容)等。 在文件名 "tranquil-spaces-master" 中,...

    最齐全的jqueryJS

    - `$.ajax()`是jQuery的核心异步请求函数,可以处理XMLHttpRequest和JSONP请求。 - `$.get()`, `$.post()`是对`$.ajax()`的简写,分别用于GET和POST请求。 - `$.getJSON()`专门用于获取JSON数据,方便数据的处理...

    jquery suggest插件

    2. **设置数据源**:可以使用Ajax请求动态获取数据,也可以直接使用JSON格式的静态数据。 3. **初始化插件**:通过jQuery选择器找到输入框元素,然后调用`.suggest()`方法,传递配置对象,例如设置数据源、匹配策略...

    人类预期寿命数据(世界各国)1960-2022年.xlsx

    介绍 人类预期寿命是指在特定年龄出生的人群,按照当前的死亡率水平,预期平均能够存活的年数。预期寿命衡量一个国家和地区卫生健康状况、社会经济发展水平和生活条件的重要参数 数据来源为世界银行、第四-七次全国人口普查数据 ## 一、人类预期寿命趋势 2022年,全球人类预期平均寿命为72岁。其中女性为74.5岁,男性为69.6岁 世界银行的数据显示,1960-2022年期间,人类预期寿命整体呈上升趋势。随着医疗技术的进步、公共卫生的改善、营养条件的提升以及生活方式的改变,这62年间,人类平均预期寿命提升了21岁。受到新冠疫情的影响,2021年,预期寿命有所下降,但在2022年有所回升

    光伏超级电容与蓄电池混合储能系统能量管理仿真:模型、算法及应用场景

    内容概要:本文深入探讨了光伏超级电容与蓄电池混合储能系统在能量管理方面的仿真研究。主要内容涵盖光伏Boost模块的最大功率点跟踪(MPPT)算法实现、蓄电池与超级电容的分工及其控制策略、仿真工况的设计与分析。文中不仅提供了详细的数学模型和控制算法,还展示了具体的仿真案例,如200Hz投切负载和光照突降测试,验证了系统的动态响应能力和稳定性。此外,文章强调了仿真过程中需要注意的关键技术和参数设置,为实际应用提供了宝贵的理论支持和技术指导。 适合人群:从事新能源技术研发的专业人士、高校师生及相关领域的研究人员。 使用场景及目标:适用于光伏储能系统的研究与开发,旨在提高系统的能量利用效率和稳定性,特别是在面对复杂工况时的表现。通过仿真研究,可以优化系统设计,降低成本,提升性能。 其他说明:文中提供的代码片段和仿真模型仅供参考,在实际应用中需要结合具体情况进行调整和完善。同时,建议参考更多相关领域的权威文献,以确保研究成果的科学性和可靠性。

    基于FPGA与Verilog的多波形实时可调DDS信号发生器设计

    内容概要:本文详细介绍了利用FPGA和Verilog实现的一个能够实时切换六种波形并进行频率调节的DDS信号发生器的设计。文中首先阐述了波形切换机制,通过ROM查表法实现不同波形的数据存储与读取;接着讲解了按键交互设计,确保用户可以通过三个按键轻松地控制设备的功能;然后讨论了频率调节方法,采用相位累加器实现精确的频率控制;此外,还探讨了ASK和FSK调制的具体实现方式以及一些优化技巧如PWM替代DAC等。最终经过测试验证,该发生器可以在1kHz到10MHz范围内平稳运行,具有良好的性能表现。 适合人群:对FPGA开发有一定了解的技术爱好者、电子工程专业学生或者从事相关领域的工程师。 使用场景及目标:适用于需要生成多种标准波形并且可以灵活调整输出频率的应用场合,例如实验室环境下的教学演示、科研实验或是产品原型开发阶段。 其他说明:文中提供了大量具体的Verilog代码片段作为参考,帮助读者更好地理解和复现整个项目。同时提到了一些常见问题及其解决方案,有助于初学者避开潜在陷阱。

    ABAQUS有限元软件中刀盘切削竹材模型的构建与应用

    内容概要:本文详细介绍了使用 ABAQUS 有限元软件构建刀盘切削竹材模型的方法。首先,设定了刀具的工作参数,如转速和进给速度。接着,通过创建部件、定义材料属性、装配部件、设置分析步和划分网格等步骤完成了整个模型的建立。文中还强调了材料定义的关键性,特别是竹材作为复合材料层时使用的 Hashin 准则。此外,讨论了刀具运动的设置方法,包括旋转和平移动态的组合。对于接触设置部分,则探讨了摩擦系数和损伤耦合的影响。最后,提供了模型验证的一些技巧,确保仿真结果的有效性和准确性。 适合人群:从事机械工程、材料科学及相关领域的研究人员和技术人员,尤其是对有限元分析有一定基础的人群。 使用场景及目标:适用于需要研究刀具切削竹材过程的工程项目,旨在帮助工程师们更好地理解和优化切削工艺,提高生产效率和产品质量。 其他说明:文章不仅涵盖了理论知识,还包括了大量的代码片段和实践经验,有助于读者快速掌握相关技能并在实际工作中加以运用。

    光电探测器仿真:温度特性仿真.zip

    光电材料仿真,电子仿真等;从入门到精通教程;含代码案例解析。

    Python计算机课程设计项目:基于改进UNet和GAN的图像修复系统

    基于生成对抗网络(GAN)的图像修复算法,旨在通过利用深度学习技术修复图像中的缺陷和损坏区域。算法中包括两个主要组件:一个生成器(Generator)和一个判别器(Discriminator)。生成器使用的是无注意力机制的全卷积架构UNet,而判别器采用的是PatchGAN架构。预处理过程中,加载图像和掩码文件并调整大小,进行随机掩码应用,准备模型输入。生成器根据对抗损失、感知损失和结构一致性损失调整其参数,以改善生成图像的质量和真实性。判别器评估两类图像:真实的未损坏图像和生成器产生的修复图像。通过设计生成器和判别器,算法能够有效地处理和修复图像中的缺陷。

    基于PLC1200与Factory IO的虚拟工厂仿真设计及调试经验分享

    内容概要:本文详细介绍了利用西门子TIA Portal V15.1和Factory IO构建虚拟工厂仿真的全过程。首先讲述了环境搭建,包括选择合适的PLC型号(如S7-1200)、正确配置通信参数(如IP地址)以及启用必要的通信权限。接着深入探讨了Factory IO场景的创建,强调了合理的信号映射和物理属性设置对于仿真效果的影响。随后展示了PLC程序的设计思路,特别是状态机的应用和关键逻辑的实现方法。文中还记录了一些常见的调试问题及其解决方案,例如因变量映射错误导致的传送带异常加速现象。最后分享了作者在联机调试过程中积累的经验教训,如使用Ping命令检查网络连通性和调整定时器参数避免误触发等。 适合人群:从事工业自动化领域的工程师和技术爱好者,尤其是对PLC编程和虚拟仿真感兴趣的初学者。 使用场景及目标:帮助读者掌握如何使用TIA Portal和Factory IO进行虚拟工厂仿真系统的搭建与调试,提高编程技能并减少实际项目中的试错成本。 其他说明:文中提供了大量实用的技术细节和实战案例,有助于加深理解和应用。同时提醒读者注意一些容易忽视的小问题,如IP地址配置、变量映射等,这些都是确保系统稳定运行的关键因素。

    Comsol金属贴片建模与多极子展开分析:电磁学领域的透反射计算及应用

    内容概要:本文详细介绍了如何使用Comsol进行金属贴片建模及其多极子展开分析,特别关注于透反射计算。首先,文章讲解了金属贴片建模的具体步骤,包括选择合适的物理场、绘制几何图形、设定材料属性等。接着,探讨了多极子展开的基础理论及其在Comsol中的实现方式,解释了多极子如电偶极子和磁偶极子如何影响电磁波的散射行为。随后,讨论了透反射计算的方法,强调了边界条件和求解器设置的重要性,并展示了如何通过多极子分解来分析透反射系数的变化。最后,文章还分享了一些实用技巧,如参数化扫描、网格优化和多极子分解的实际操作方法。 适合人群:从事电磁学研究的专业人士、研究生及以上学历的研究人员、对电磁仿真感兴趣的工程师。 使用场景及目标:适用于科研项目中涉及金属贴片结构的设计与分析,帮助研究人员更好地理解和预测金属贴片在不同电磁环境下的表现,尤其是透反射特性和多极子效应的应用。 其他说明:文中提供了详细的建模步骤和代码片段,便于读者动手实践并加深理解。同时,针对可能出现的问题给出了具体的解决方案,确保仿真的准确性。

    郑予彬-生成式AI提升开发者效能.pdf

    郑予彬-生成式AI提升开发者效能.pdf

    基于MATLAB的三自由度车辆动力学模型与CKF算法的质心侧偏角估计及联合仿真

    内容概要:本文详细介绍了基于MATLAB的三自由度车辆动力学模型以及利用容积卡尔曼滤波(CKF)进行车辆质心侧偏角估计的方法。首先,文章解释了三自由度模型的基本原理,包括状态方程的构建和线性轮胎模型的应用。接着,深入探讨了CKF算法的具体实现,包括容积点生成、预测和更新步骤,并展示了其相对于扩展卡尔曼滤波(EKF)的优势。此外,文章还讨论了与CarSim软件的联合仿真过程中遇到的问题及解决方案,如时钟同步和参数调试技巧。最终,通过实验验证了CKF在车辆状态估计中的高效性和准确性。 适合人群:从事车辆动力学研究、自动驾驶技术研发的专业人士,尤其是有一定MATLAB编程基础的研究人员和技术人员。 使用场景及目标:适用于需要精确估计车辆状态(如质心侧偏角、横摆角速度等)的场合,旨在提高自动驾驶系统的感知能力和控制精度。目标是帮助研究人员更好地理解和应用CKF算法,优化车辆控制系统的设计。 其他说明:文中提供了详细的代码片段和调试经验分享,有助于读者快速上手并解决实际问题。同时,强调了在特定工况下(如低附着力路面)采用自适应CKF的重要性。

    轴承故障诊断中的一维CNN与MMD-Coral迁移学习方法及其应用

    内容概要:本文详细介绍了使用一维CNN结合MMD(最大均值差异)和Coral(协方差对齐)进行轴承故障诊断的迁移学习方法。主要内容涵盖数据预处理、网络模型设计、域适应技术以及训练技巧等方面。文中使用西储大学CWRU数据集进行实验,通过滑动窗口切片、归一化等手段处理振动信号,并构建了一维CNN模型,利用MMD和Coral实现源域和目标域的特征对齐。最终模型取得了99%的准确率,验证了方法的有效性。 适合人群:对机器学习特别是迁移学习感兴趣的初学者和技术爱好者。 使用场景及目标:适用于需要解决不同工况下轴承故障诊断问题的研究人员和工程师。主要目标是通过迁移学习提高模型在新环境下的泛化能力。 其他说明:文章不仅提供了详细的理论解释,还包括具体的代码实现和可视化工具的应用,如损失曲线图、准确率曲线图、混淆矩阵和t-SNE图等,有助于读者更好地理解和评估模型性能。此外,作者还分享了一些实用的经验和技巧,例如如何设置超参数、选择合适的学习率调度器等。

    电子信息工程巴特沃斯低通滤波器设计与仿真

    打包了西安电子科技大学B级测试低通滤波器设计,属于巴特沃斯低通滤波器,包含电路仿真、报告、matlab仿真,适合初学者以及西电学生作参考使用。

    光电探测器仿真:光电探测器基础理论.zip

    光电材料仿真,电子仿真等;从入门到精通教程;含代码案例解析。

    natsort-6.0.0-py2.py3-none-any.whl

    该资源为natsort-6.0.0-py2.py3-none-any.whl,欢迎下载使用哦!

    这篇文章详细介绍了基于积分时滞模型(Integral Delay Model, ID Model)的渠道水位预测控制算法的研究与实现,主要围绕模型预测控制(MPC)展开 论文复现或解答具体内容如下:

    内容概要:本文详细介绍了基于积分时滞模型(ID Model)的渠道水位预测控制算法,主要聚焦于模型预测控制(MPC)框架下的实现。文章首先概述了论文的核心内容,即通过MPC结合渠道仿真模型和简化预测模型来实现水位控制。接着,通过详细的代码实现展示了从环境准备、渠道参数设置、SWMM模型构建、简化预测模型、MPC控制器实现到最后的完整仿真流程。文中还深入解析了积分时滞模型的数学原理及其参数辨识方法,并通过状态空间模型构建和滚动优化策略,实现了多渠段渠道水位的精准控制。此外,文章还提供了完整的性能评估和可视化展示,确保算法的有效性和适应性。 适合人群:具备一定编程基础,尤其是熟悉Python编程语言的研发人员,以及从事水利、自动化控制领域研究的专业人士。 使用场景及目标:①帮助读者理解如何利用SWMM模型和MPC算法实现渠道水位控制;②掌握积分时滞模型的数学原理及其在预测控制中的应用;③学习如何通过Python代码实现从模型构建到性能评估的完整流程;④提供实际案例,便于研究人员和工程师在实际项目中应用和改进该算法。 其他说明:本文不仅提供了详细的代码实现和理论解析,还强调了实际应用中的关键技术和创新点。读者可以通过跟随代码逐步实践,深入理解MPC在渠道水位控制中的应用,并根据具体需求进行扩展和优化。

    espidf启动流程基于esp32c3

    espidf启动流程

Global site tag (gtag.js) - Google Analytics