Dojo 的Ajax, dojo/request <14>
发布时间:2020-12-16 21:30:00 所属栏目:百科 来源:网络整理
导读:dojo/request 是创建从客户端到服务器端请求的一个新的API(1.8引入). 这个教程将介绍dojo/request API: 如何从服务器获请求一个文本文件, 当请求发现问题时如何处理。使用更高级的通知API,向服务器提交信息, 以及使用注册功能实现相同的代码请求不同处的
dojo/request 是创建从客户端到服务器端请求的一个新的API(1.8引入). 这个教程将介绍dojo/request API: 如何从服务器获请求一个文本文件, 当请求发现问题时如何处理。使用更高级的通知API,向服务器提交信息, 以及使用注册功能实现相同的代码请求不同处的数据。 开始
dojo/request 允许你不需要重新加载页面的情况下,向服务器发接和接受数据(通常称为AJAX). 引入的新代点使得代码更加简洁,执行更为快速。 这个教程里提及的dojo/promise和dojo/Deferred,是dojo/request使用到的异步编程模式。因为不可能在一个教程里什么都讲,所以不会深入了
解Promises 和Deferred. 只需记住Promise和Deferred允许非阻塞异步编程更加容易。 在看完本教程后,你可以去看看这些教程。
介绍 dojo/request
先看看一个简单的例子:
require(["dojo/request"],function(request){ request("helloworld.txt").then( function(text){ console.log("The file's content is: " + text); },function(error){ console.log("An error occurred: " + error); } ); }); 在浏览器里, 以面的代码将会使用XMLHttpRequest 执行一个HTTP GET的请求,请求的资源为 helloworld.txt 并且返回一个 dojo/promise/Promise. 如果请求成功, then里的第一个函数会被执行,返回的文本也会作为唯一的参数传递给函数。 如果请求失败, then的第二个回调函数会被执行, 并传递一个 error 对像。 但要是给服务器发送数据? 或者返回的是JSON 或者 XML? 没问题 -dojo/reuqest API 自定义请求。 dojo/request API
每一个请求都需一件事情: 一个终点。 因为这样, dojo/request的第一个参数是 URL.
web开发者需要灵活性的工具,以适他们的应用程序和不同的环境。 dojo/request API 也考虑了这一点: 第一个, 非可选项, 请求的URL. 第二个参数自定义请求的对像。 常用的选项是:
让我们看一个使用了这些选项的例子:
require(["dojo/request"],function(request){ request.post("post-content.php",{ data: { color: "blue",answer: 42 },headers: { "X-Something": "A value" } }).then(function(text){ console.log("The server returned: ",text); }); }); 以上代码执行了一个指向 post-content.php的 post请求。 一个简单的对像(data) 被序列化然后作为请求数据发送,以及"X-somethine" 请求头也会作为请求数据发送。 当服务器响应时, 会从request.post返回promise的值。 Examples: request.get 和 request.post
以下是dojo/request常见用途
在网页中显示一个文本文件的内容
这个例子中使用dojo/request.get 请求一个文本文件。 最常用于网站的条款声明或者隐私声明。 因为只在浏览者明确需要时,才将文本文件发送给它们。 并且文件文件比嵌入了代码的文件更易于维护。
require(["dojo/dom","dojo/on","dojo/request","dojo/domReady!"],function(dom,on,request){ // Results will be displayed in resultDiv var resultDiv = dom.byId("resultDiv"); // Attach the onclick event handler to the textButton on(dom.byId("textButton"),"click",function(evt){ // Request the text file request.get("../resources/text/psalm_of_life.txt").then( function(response){ // Display the text file content resultDiv.innerHTML = "<pre>"+response+"</pre>"; },function(error){ // Display the error returned resultDiv.innerHTML = "<div class="error">"+error+"<div>"; } ); }); } );
查看示例
登录演示
在接下来的例子中,一个POST请求用于发送 username和password 到服务器, 并显示服务器返回的结果。
require(["dojo/dom","dojo/dom-form"],domForm){ var form = dom.byId('formNode'); // Attach the onsubmit event handler of the form on(form,"submit",function(evt){ // prevent the page from navigating after submit evt.stopPropagation(); evt.preventDefault(); // Post the data to the server request.post("../resources/php/login-demo.php",{ // Send the username and password data: domForm.toObject("formNode"),// Wait 2 seconds for a response timeout: 2000 }).then(function(response){ dom.byId('svrMessage').innerHTML = response; }); }); } );
查看示例
请求头演示
在接下来例子中, 使用如上的post请求,并且访问 Auth-token头部信息。
为了访问headers信息, 使用promise.reponse.getHeader 方法(原生的Promise是从XHR对像返回的,它没有这个属性,只能是 promise.response). 另外, 当使用promise.response.then,response uq将不是数据,而是一个包含数据属性的对像。
require(["dojo/dom",domForm){ // Results will be displayed in resultDiv var form = dom.byId('formNode'); // Attach the onsubmit event handler of the form on(form,function(evt){ // prevent the page from navigating after submit evt.stopPropagation(); evt.preventDefault(); // Post the data to the server var promise = request.post("../resources/php/login-demo.php",// Wait 2 seconds for a response timeout: 2000 }); // Use promise.response.then,NOT promise.then promise.response.then(function(response){ // get the message from the data property var message = response.data; // Access the 'Auth-Token' header var token = response.getHeader('Auth-Token'); dom.byId('svrMessage').innerHTML = message; dom.byId('svrToken').innerHTML = token; }); }); } ); 查看示例 JSON
JSON 常用于对AJAX请求的数据进行编码, 因为它的易读,易用,以及简洁的特性, JSON可用于编码任意的数据类型: JSON 支持多种语言: php,java,perl,python,ruby 和 ASP.
JSON编码后的对像
{ "title":"JSON Sample Data","items":[{ "name":"text","value":"text data" },{ "name":"integer","value":100 },{ "name":"float","value":5.65 },{ "name":"boolean","value":false }] } 当 handleAs 被设置为"json",dojo/request 会对返回的数据以JSON格式处理, 并将返回的数据解析为一个Javascript对像。 require(["dojo/dom","dojo/json","dojo/_base/array",JSON,arrayUtil){ // Results will be displayed in resultDiv var resultDiv = dom.byId("resultDiv"); // Request the JSON data from the server request.get("../resources/data/sample.json.php",{ // Parse data from JSON to a JavaScript object handleAs: "json" }).then(function(data){ // Display the data sent from the server var html = "<h2>JSON Data</h2>" + "<p>JSON encoded data:</p>" + "<p><code>" + JSON.stringify(data) + "</code></p>"+ "<h3>Accessing the JSON data</h3>" + "<p><strong>title</strong> " + data.title + "</p>" + "<p><strong>items</strong> An array of items." + "Each item has a name and a value. The type of " + "the value is shown in parentheses.</p><dl>"; arrayUtil.forEach(data.items,function(item,i){ html += "<dt>" + item.name + "</dt><dd>" + item.value + " (" + (typeof item.value) + ")</dd>"; }); html += "</dl>"; resultDiv.innerHTML = html; },function(error){ // Display the error returned resultDiv.innerHTML = error; }); } ); !* 另外还需要设置response以JSON来编码数据, 可以设置Content-type 的头部信息为application/json,或者使用服务器端的配置,如Apache的 addType 或者 在服务器端代码里添加 header信息。
查看 Demo
JSONP(Javascript Object Notation with Padding)
AJAX请求局性于当前的域名下。 如果你需要请求的数据是不同的域名, 你可以使用JSONP. 当使用JSONP时, 一个script 标签会被插入到当前页面, src会设置为请求文件的URL, 服务器会使用callback函数 封装数据。 并且当响应执行完时, 会调用callback 函数,并将传递返回的数据给callback. JSONP请求是通过dojo/request/script.
让我们看些例子
使用JSONP从服务器请求处据,并处理响应
require(["dojo/dom","dojo/request/script","dojo/domReady!" ],script,JSON){ // Results will be displayed in resultDiv var resultDiv = dom.byId("resultDiv"); // Attach the onclick event handler to the makeRequest button on(dom.byId('makeRequest'),function(evt){ // When the makeRequest button is clicked,send the current // date and time to the server in a JSONP request var d = new Date(),dateNow = d.toString(); script.get("../resources/php/jsonp-demo.php",{ // Tell the server that the callback name to // use is in the "callback" query parameter jsonp: "callback",// Send the date and time query: { clienttime: dateNow } }).then(function(data){ // Display the result resultDiv.innerHTML = JSON.stringify(data); }); }); }); 由于响应是Javascript, 而不是Json,响应的头部信息 Content-Type应该设置为application/javascript
查看示例
使用JSONP来请求Github API上的 dojo pull请求.
require(["dojo/dom","dojo/dom-construct",domConstruct,arrayUtil){ var pullsNode = dom.byId("pullrequests"); // Attach the onclick event handler to tweetButton on(dom.byId("pullrequestsButton"),function(evt){ // Request the open pull requests from Dojo's GitHub repo script.get("https://api.github.com/repos/dojo/dojo/pulls",{ // Use the "callback" query parameter to tell // GitHub's services the name of the function // to wrap the data in jsonp: "callback" }).then(function(response){ // Empty the tweets node domConstruct.empty(pullsNode); // Create a document fragment to keep from // doing live DOM manipulation var fragment = document.createDocumentFragment(); // Loop through each pull request and create a list item // for it arrayUtil.forEach(response.data,function(pull){ var li = domConstruct.create("li",{},fragment); var link = domConstruct.create("a",{href: pull.url,innerHTML: pull.title},li); }); // Append the document fragment to the list domConstruct.place(fragment,pullsNode); }); }); });查看Demo 状态报告
dojo/request/notify 提供了一个报告请求状态的机制。 加载完dojo/request/nofity模块后,它允许请求的提供者(request,response,request.get,request)可以触发事件,这些事件可以用于监听和报告request的状态。 为了监听一个事件, 调用dojo/request/notify模块的返回值,并传递两个参数给它: 事件名称 和 监听函数。 dojo/request的请求提供者,可以触发以下事件:
dojo/request/notify 支持的事件类型
start和stop的监听器不会接受参数。 send的监听器接受两个参数: 一个代表request 对像象 和一个cancel 函数。 调用 cancel函数将会在请求开始前取消这个请求。 "load","error","done"的监听器只有一个参数: 服务器的响应对像。 让我们看看实际的例子。
使用 dojo/request/notify 监控请求的进度
require(["dojo/dom","dojo/request/notify","dojo/query",notify,domConstruct){ // Listen for events from request providers notify("start",function(){ domConstruct.place("<p>Start</p>","divStatus"); }); notify("send",function(data,cancel){ domConstruct.place("<p>Sent request</p>","divStatus"); }); notify("load",function(data){ domConstruct.place("<p>Load (response received)</p>","divStatus"); }); notify("error",function(error){ domConstruct.place("<p class="error">Error</p>","divStatus"); }); notify("done",function(data){ domConstruct.place("<p>Done (response processed)</p>","divStatus"); if(data instanceof Error){ domConstruct.place("<p class="error">Error</p>","divStatus"); }else{ domConstruct.place("<p class="success">Success</p>","divStatus"); } }); notify("stop",function(){ domConstruct.place("<p>Stop</p>","divStatus"); domConstruct.place("<p class="ready">Ready</p>","divStatus"); }); // Use event delegation to only listen for clicks that // come from nodes with a class of "action" on(dom.byId("buttonContainer"),".action:click",function(evt){ domConstruct.empty("divStatus"); request.get("../resources/php/notify-demo.php",{ query: { success: this.id === "successBtn" },handleAs: "json" }); }); } ); dojo/request/registry
dojo/request/registry 为请求提供了一种基于URL的路由机制。registry 常用于为JSON 或者 JSONP分配请求提供者(XHR或者Script). 你也可以用于一个URL会经常变化的情况。
dojo/request/registry 语法
request.register(url,provider,first); dojo/request/registry 参数
regExp - 如果是正则表达式, 当正则表达式与请求的URL匹配时,提供者才会被使用
function - 如果url是一个函数, 将会传递URL和一个可选的request 对像给这个函数。 如果函数返回true,provider才会被使用。
使用dojo/request/registry 来基于不同请求的URL来分配 提供者(provider)
require(["dojo/request/registry","dojo/dom",function(request,dom,domConstuct,on){ // Registers anything that starts with "http://" // to be sent to the script provider,// requests for a local search will use xhr request.register(/^https?:///i,script); // When the search button is clicked on(dom.byId("searchButton"),function(){ // First send a request to twitter for all tweets // tagged with the search string request("http://search.twitter.com/search.json",{ query: { q:"#" + dom.byId("searchText").value,result_type:"mixed",lang:"en" },jsonp: "callback" }).then(function(data){ // If the tweets node exists,destroy it if (dom.byId("tweets")){ domConstuct.destroy("tweets"); } // If at least one result was returned if (data.results.length > 0) { // Create a new tweet list domConstuct.create("ul",{id: "tweets"},"twitterDiv"); // Add each tweet as an li while (data.results.length>0){ domConstuct.create("li",{innerHTML: data.results.shift().text},"tweets"); } }else{ // No results returned domConstuct.create("p",{id:"tweets",innerHTML:"None"},"twitterDiv"); } }); // Next send a request to the local search request("../resources/php/search.php",{ query: { q: dom.byId("searchText").value },handleAs: "json" }).then( function(data){ dom.byId('localResourceDiv').innerHTML = "<p><strong>" + data.name + "</strong><br />" + "<a href="" + data.url + "">" + data.url + "</a><br />"; },function(error){ // If no results are found,the local search returns a 404 dom.byId('localResourceDiv').innerHTML = "<p>None</p>"; } ); }); } ); 查 看 demo 最佳实现
dojo/request注意事项:
总结
dojo/request 为请求(当前域名的请求或者其它域名的请求)提代了一个跨浏览器兼容 的AJAX 接口,包括优雅的错误处理, 支持通知 和 基于 URL路由请求。 dojo/request会返回一个promise(承诺), 它允许异步发送和处理一系列的请求。 网页可以包含多个源的内容, 并且使用每个请求数据。 用dojo/request 来增加你的页面吧!
资源
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容