まず第一に、私は学部時代に SSH フレームワークのバックエンド Java 開発を勉強しました (私は完全にめちゃくちゃでした)。通常、Web プロジェクトを開発する場合、JSP を使用してページを直接表示すると、さまざまなフォームが送信され、アクションがジャンプするため、データを更新する必要があると、たとえ小さな部分であってもページを更新する必要があります。これは非常に面倒で、ユーザーエクスペリエンスに影響を与えます。私はテクノロジーを使ってこの問題を解決したいと常々思っていました。で、プライベートでしばらく悩んだ末に ajax について調べてみたところ、 struts2 が ajax に完全対応していることがわかったので、同じ経験をした人の参考になればと思いこの記事を書きました! (追記:仕事後にプライベートでクラスメートに聞かれることが多いので、参考までに整理しました!)
この記事では主に struts2 環境での ajax アプリケーションについて説明します。したがって、struts2 の関連するすべての jar パッケージを事前に Web プロジェクトにインポートする必要があることは、ここでは詳しく説明しませんが、json データをサポートするために追加の jar パッケージをインポートする必要があることをご存知でしょう。 ;jar パッケージを添付ファイルとして送信します。基本的に、これを完了したら、開始する準備は完了です。
2 つの例を詳しく説明します。1 つは ajax リクエストの特定のプロセスを説明するために使用され、もう 1 つは実際のアプリケーションに関連し、パラメーターに従って対応するデータを返します。
最初にコード 1 を投稿します (便宜上、JSP コードは投稿しませんでした。実際には、これは 内の一部の構成項目にすぎません) > タグ。読者は自分でコピーできます)
标签一些配置项而已,读者可以自己复制)
<!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8"> <title>XHR</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <style> form, .box { margin: 50px; padding: 20px; } form p { margin: 20px 0; } .box { background-color: rgba(0, 0, 0, 0.2); height: 40px; width: 300px; } </style></head><body> <form id="form"> <p><label for="nick">昵称:</label> <input value="jero" name="nick" id="nick" type="text" required></p> <p><label for="love">爱好:</label> <input value="coding" name="love" id="love" type="text" required></p> <p> <button type="button" name="get">Get 提交</button> <button type="button" name="post">Post 提交</button> </p> </form> <p id="box" class="box"></p> <script> var byId = (id) => document.getElementById(id); // ES6 箭头函数 var form = byId('form'); var box = byId('box'); /** * 表单的数据收集起来 */ function getData(type) { var result = []; var isFill = false; // 都是文本框的 name ['nick', 'love'].forEach((fieldName) => { var v = form[fieldName].value; var obj = {}; if (v) { obj[fieldName] = v; result.push(obj); isFill = true; } else { isFill = false; } }); if (!isFill) { // 没填的话要返回没填的结果 false return false; } result = JSON.stringify(result); result = "info" + '=' + encodeURIComponent(result) return result; } function request(type, callback) { var data = getData(type); if (!data) { // 没填的话直接警告 return alert("完成表单!"); } var xhr = new XMLHttpRequest(); xhr.onreadystatechange = () => { if (xhr.readyState === 4) { callback(JSON.parse(xhr.responseText), xhr); } else { console.log(xhr.status); } } xhr.open(type, './xhr' + (type === 'get' ? `?${data}` : '')); // get 的参数直接拼在 url 的末尾 // 模拟 post 请求,必须设置个请求头 if (type === 'post') { xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')//可以自己根据实际情况改变取值 } xhr.send(type === 'get' ? null : data); } /** * 绑定事件抽象下 */ function click(btn, callback) { btn.addEventListener('click', () => { request(btn.name, (data) => { var data = JSON.parse(data); box.innerHTML = `success by ${data[0].type} method!<br> ${data[0].infoStr}`; console.log(data); }); }); } // 绑定事件,代码可以从这里看 click(form.get); click(form.post) </script></body></html>
页面运行效果
上面代码中有几处在这说一下。1.encodeURIComponent()
这个函数是用来把变量转换成url地址中的字符串,避免传值时出现乱码。2.当使用var form = document.getElementById('form')
获取到form表单节点时,我们可以直接使用form.nick
或者form[nick]
来直接获取昵称输入框节点,当然前提是form表单中的元素且设置了name
属性。
然后我们来重点解读下这段代码:
function request(type, callback) { var data = getData(type);//参数列表字符串 if (!data) { // 没填的话直接警告 return alert('完成表单!'); } var xhr = new XMLHttpRequest();//生成XHR对象 xhr.onreadystatechange = () => { if (xhr.readyState === 4) { callback(JSON.parse(xhr.responseText), xhr);//数据成功接收后的回调函数 } else { console.log(xhr.status); } } xhr.open(type, './xhr' + (type === 'get' ? `?${data}` : '')); // get 的参数直接拼在 url 的末尾 // 模拟 post 请求,必须设置个请求头 if (type === 'post') { xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')//可以自己根据实际情况改变取值 } xhr.send(type === 'get' ? null : data); }
首先,明确一点这个函数的作用就是发送ajax请求;这里我采用了原生的XHR对象来实现ajax请求,目的是让大家能够深刻理解到ajax 是怎么样一回事;总体来说发送ajax请求分为四步:
IE7以上以及现在主流的浏览器都支持原生的XHR对象,所以我们可以直接用var xhr = new XMLHttpRequest();
来创建XHR对象,用XHR对象所封装的一些方法来实现ajax请求。至于IE7以下的毒瘤,我是绝对不会做考虑的!如果你硬要做IE7以下的兼容可以参考js红皮书ajax章节。是通过ActiveX对象来创建的!
xhr.onreadystatechange
实现监听请求响应过程所处的的阶段。主要是通过XHR对象的readyState
属性;属性的取值为:
0-未初始化(未调用open()方法)
1-启动(调用open()方法,未调用send()方法)
2-发送(调用send()方法,但没有得到响应、没有接收到数据)
3-接收(接收到部分数据)
4-完成(得到全部响应数据)
当属性值每发生一次变化,就触发一次readystatechange事件。所以我们可以通过这个属性的值来判断我们所需的数据是否准备就绪。以便及时地将我们所请求的数据渲染到页面中去。
而xhr.status
返回的则是HTTP请求的状态码( 学过网络的同学应该都了解),这就方便我们检测请求是否成功,亦或者判断请求失败的原因。 callback(JSON.parse(xhr.responseText), xhr);
xhr.open(type, './xhr' + (type === 'get' ??${data}: ''));
encodeURIComponent()
この関数は、値を渡すときに文字化けを避けるために、変数を URL アドレスの文字列に変換するために使用されます。 2. var form = document.getElementById('form')
を使用してフォーム ノードを取得する場合、form.nick
または form[nick ] を直接使用できます。
を使用してニックネーム入力ボックス ノードを直接取得します。もちろん、フォーム内の要素に name
属性が設定されていることが前提となります。 それでは、このコードの解釈に焦点を当てましょう:
xhr.send(type === 'get' ? null : data);最后一个环节,上面说到的post传参就要在这传入,get则不用,所以在这里同样用了一个三目运算。
var xhr = new XMLHttpRequest();
を使用して XHR オブジェクトを作成し、XHR オブジェクトによってカプセル化されたいくつかのメソッドを使用して Ajax リクエストを実装します。 IE7 以下のガンについては、決して考慮しません。 IE7 以下との互換性を確保したい場合は、js レッドブックの ajax の章を参照してください。 ActiveX オブジェクトを通じて作成されます。 🎜🎜2. リスニング関数をバインドする 🎜🎜xhr.onreadystatechange
は、監視リクエストの応答プロセスの段階を実装します。主に ) メソッドの readyState
属性を使用します) 🎜2-Send (send() メソッドを呼び出しますが、応答もデータも受信しません) 🎜3-Receive (データの一部を受信します) 🎜4 -Complete (すべての応答データを取得) 🎜属性値が発生したとき 変更により、readystatechange イベントがトリガーされます。したがって、この属性の値を使用して、必要なデータが準備できているかどうかを判断できます。リクエストしたデータをタイムリーにページにレンダリングするため。 🎜そして、xhr.status
は HTTP リクエストのステータス コードを返します (ネットワークを勉強したことがある学生なら誰でも知っているはずです)。これにより、リクエストが成功したかどうかを検出したり、リクエストが成功したかどうかを判断したりすることが容易になります。リクエストが失敗した理由。 🎜callback(JSON.parse(xhr.responseText), xhr);
これは、すべてのデータを受信したときに実行されるコールバック関数であり、主に受信したデータを処理し、ページをレンダリングするために使用されます。 。実際のアプリケーションではこれに従うことができます。バインディング関数でのコールバック関数の記述に重点が置かれています。実際のニーズに応じて記述してください。 🎜🎜3. リクエストを開始します🎜$.ajax(function() { url: 'xhr', type: 'get', dataType: 'json',//返回数据类型 data: {info: data},//传参 success: function(data) { /***/ }, error: function() { console.log('error!'); } });
xhr.send(type === 'get' ? null : data);最后一个环节,上面说到的post传参就要在这传入,get则不用,所以在这里同样用了一个三目运算。
基本上,原生的XHR对象实现ajax请求就如上所说;是不是觉得有点复杂?那么不用慌,喜欢“偷懒”的高端程序猿已经帮我们实现了封装;没错就是当初影响世界的jQuery。话不多说,直接上代码:
$.ajax(function() { url: 'xhr', type: 'get', dataType: 'json',//返回数据类型 data: {info: data},//传参 success: function(data) { /***/ }, error: function() { console.log('error!'); } });
jQuery提供了很多种写法,包括更简单的$.getJSON()
;至于我为什么要推荐这种写法,大家可以理解成我很笨,但是其中的含义大家用过就明白了!(吹个小牛皮)
上面说了这么多,一是让大家了解原生的是怎样的一个东西,二是因为上述部分是学习后台同学没有接触过的,所以尽可能的讲清楚点;这部分,我想代码一贴出来,大家都懂了!
action
package com.testforajax.demo.action;import java.util.ArrayList;import java.util.HashMap;import java.util.Map;import org.apache.struts2.ServletActionContext;import net.sf.json.JSONArray;import net.sf.json.JSONObject;import com.opensymphony.xwork2.ActionSupport;public class AjaxDemo extends ActionSupport { private String info; public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } public String execute() throws Exception { String method = ServletActionContext.getRequest().getMethod(); HashMap<String, String> map = new HashMap<String, String>(); String name; String love; JSONArray json = JSONArray.fromObject(info); name = json.getJSONObject(0).getString("nick"); love = json.getJSONObject(1).getString("love"); json.clear(); String result = name + " very love " + love; map.put("type", method); map.put("infoStr", result); json.add(map); info = json.toString(); System.out.println(this.info); return "success"; } }
struts.xml
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"><struts> <!-- XHR演示 --> <package name="xhrTest" extends="json-default, struts-default"> <action name="xhr" class="com.testforajax.demo.action.AjaxDemo"> <result type="json"> <param name="root">info</param> </result> </action> <!-- <action name="newxhr" class="com.testforajax.demo.action.AjaxDemo2"> <result type="json"> <param name="root">queryId</param> </result> </action> --> </package></struts>
在这里只强调一点,struts2的自动打包传值,一定要保证参数名一致!即你在前台封装json数据格式时,对应的key值要和struts.xml配置文件中<param name="root">info
一致,同时在action类中也要有对应的属性,以及getter和setter。
还有,在使用json数据格式时要做到传参时记得JSON.stringify()
,渲染响应数据时记得JSON.parse()
。封装时,一定要按照标准格式,后台封装的话,推荐我写的那种先用map做处理。
以上がAjax の簡単な分析と実際の操作の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。