黑马AJAX

1、Ajax的运行原理以及实现

1.1 Ajax的运行环境

 使用node开启服务器,代码写在html中,再放进静态资源文件夹中,就可以使用域名访问了

1.2 Ajax的运行原理

 实现无刷新更新数据,边浏览边请求响应。并且ajax请求和响应是可控的,并且可以反馈给用户。

1.3 Ajax的实现步骤

首先开启服务器 nodemon app.js

    <script type="text/javascript"> //客户端
      // 1.创建ajax对象
      var xhr = new XMLHttpRequest();
      // 2.告诉Ajax对象要向哪发送请求,以什么方式发送请求
      // 1)请求方式 2)请求地址
      xhr.open("get", "http://localhost:3000/first");
      // 3.发送请求
      xhr.send();
      // 4.获取服务器端响应到客户端的数据
      xhr.onload = function () {
        console.log(xhr.responseText);
      };
    </script>
 


// 对应01html文件 服务器段
app.get('/first', (req, res) => {
	res.send('Hello, Ajax'); //为客户端响应文字
});

因为send(0 方法后,接受会受网络的影响,所以写一个onload等待他的响应

监听xhr对象的onload事件,完成之后获取响应数据console.log(xhr.responseText);这里面就是res.send(“ Hello,Ajax”) 但是知识字符串格式。

  JSON.parse()方法,它是Windows下面的方法

		xhr.onload = function (){
			// console.log(typeof xhr.responseText)
			// 将JSON字符串转换为JSON对象
			var responseText = JSON.parse(xhr.responseText);
			// 测试:在控制台输出处理结果
			console.log(responseText)
			// 将数据和html字符串进行拼接
			var str = '<h2>'+ responseText.name +'</h2>';
			// 将拼接的结果追加到页面中
			document.body.innerHTML = str;
		}

 需要把json字符串转换为json对象,此时上面的responseText就是一个对象了。接受的json和html拼接,然后添加DOM到html中,

 1.4 请求参数的传递

传统网站

 1.4.1 GET的提交

其实就是open()里面的参数写法改变了

 	<script type="text/javascript">
		// 获取按钮元素
		var btn = document.getElementById('btn');
		// 获取姓名文本框
		var username = document.getElementById('username');
		// 获取年龄文本框
		var age = document.getElementById('age');
		// 为按钮添加点击事件
		btn.onclick = function () {
			// 创建ajax对象
			var xhr = new XMLHttpRequest();
			// 获取用户在文本框中输入的值
			var nameValue = username.value;
			var ageValue = age.value;
			// 拼接请求参数
			var params = 'username='+ nameValue +'&age=' + ageValue;
			// 配置ajax对象
			xhr.open('get', 'http://localhost:3000/get?'+params);
			// 发送请求
			xhr.send();
			// 获取服务器端响应的数据
			xhr.onload = function () {
				console.log(xhr.responseText)
			}
		}
	</script>

app.get('/get', (req, res) => {
	res.send(req.query);
});

req.query对象就是服务器端接受客户端传过来的GET请求参数,res.send(req.query);再把它响应到客户端。

 1.4.1 POST的提交

post是放在send()中的

btn.onclick = function () {
			// 创建ajax对象
			var xhr = new XMLHttpRequest();
			// 获取用户在文本框中输入的值
			var nameValue = username.value;
			var ageValue = age.value;
			// 拼接请求参数
			var params = 'username='+ nameValue +'&age=' + ageValue;
			// 配置ajax对象
			xhr.open('post', 'http://localhost:3000/post');
			// 设置请求参数格式的类型(post请求必须要设置)
			xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
			// 发送请求
			xhr.send(params);
			// 获取服务器端响应的数据
			xhr.onload = function () {
				console.log(xhr.responseText)
			}

// 服务器端对于post的请求参数要用const bodyParser = require('body-parser');
app.post('/post', (req, res) => {
	res.send(req.body); //相应回客户端
});

 var params = 'username='+ nameValue +'&age=' + ageValue;

如果请求参数是params中的,那么下面就是固定写法

xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

1.5 请求参数的格式

请求方式必须是post,get请求不能提交json对象数据格式

请求头必须是 "application/json"

必须转换成字符串类型

    <script type="text/javascript">
      // 1.创建ajax对象
      var xhr = new XMLHttpRequest();
      // 2.告诉Ajax对象要向哪发送请求,以什么方式发送请求
      // 1)请求方式 2)请求地址
      xhr.open("post", "http://localhost:3000/json");
      // 通过请求头告诉服务器端 客户端向服务器端传递的请求参数的格式是什么
      xhr.setRequestHeader("Content-Type", "application/json");
      // JSON.stringify() 将json对象转换为json字符串
      // 3.发送请求
      xhr.send(JSON.stringify({ name: "lisi", age: 50 }));
      // 4.获取服务器端响应到客户端的数据
      xhr.onload = function () {
        console.log(xhr.responseText);
      };
    </script>

获得服务器端的响应(Ajax状态码)

获取Ajax状态码,xhr.readyState //获取Ajax状态码

<script type="text/javascript">
      var xhr = new XMLHttpRequest();
      // 0 已经创建了ajax对象 但是还没有对ajax对象进行配置
      console.log(xhr.readyState);
      xhr.open("get", "http://localhost:3000/readystate");
      // 1 已经对ajax对象进行配置 但是还没有发送请求
      console.log(xhr.readyState);

      // 当ajax状态码发生变化的时候出发
      xhr.onreadystatechange = function () {
        // 2 请求已经发送了
        // 3 已经接收到服务器端的部分数据了
        // 4 服务器端的响应数据已经接收完成
        console.log(xhr.readyState);
        // 对ajax状态码进行判断 如果状态码的值为4就代表数据已经接收完成了
        if (xhr.readyState == 4) {
          console.log(xhr.responseText);
        }
      };
      xhr.send();
    </script>

app.get('/readystate', (req, res) => {
	res.send('hello');  
});

 xhr.onreadystatechange = function () 状态码发生变化时候自动触发

res.send('hello');  是发送给服务器的     console.log(xhr.responseText);是获取服务器的数据

1.6 Ajax错误处理

<script type="text/javascript">
		var btn = document.getElementById('btn');

		btn.onclick = function () {
			// 1.创建ajax对象
			var xhr = new XMLHttpRequest();
			// 2.告诉Ajax对象要向哪发送请求,以什么方式发送请求
			// 1)请求方式 2)请求地址
			xhr.open('get', 'http://localhost:3000/error');
			// 3.发送请求
			xhr.send();
			// 4.获取服务器端响应到客户端的数据
			xhr.onload = function (){
				// xhr.status 获取http状态码
				console.log(xhr.responseText);

				if (xhr.status == 400) {
					alert('请求出错')
				}
			}
			// 当网络中断时会触发onerrr事件
			xhr.onerror = function () {
				alert('网络中断, 无法发送Ajax请求')
			}
		}

	</script>

    // Ajax状态码: 表示Ajax请求的过程状态 ajax对象返回的
    // Http状态码: 表示请求的处理结果 是服务器端返回的

低版本IE浏览器的缓存问题,浏览器会从缓存之中取上一次的服务器响应结果,而不是实时的响应

 解决方案:xhr.open('get', 'http://localhost:3000/cache?t=' + Math.random()); 每次让请求地址不一样

2 Ajax异步编程

      xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
          console.log("2");
          console.log(xhr.responseText);
        }
      };
      console.log("1");

输出顺序:1 2 

2.1 Ajax封装

  最后的data就是请求结果

function ajax(options){
   var xhr = new XMLHttpRequest();
   xhr.open(options.type,option.url)
   xhr.send()
   xhr.onload = function(){
      options.success(xhr.responseText)
}
}  

ajax({
        type: "post",
        // 请求地址
        url: "http://localhost:3000/responseData",
        success: function (data) {
          console.log("这里是success函数");
          console.log(data);
        },
      });

 如果需要其他的参数传递进去function ajax,怎么办?

请求参数要考虑的问题:

                1.请求参数位置的问题

                    将请求参数传递到ajax函数内部, 在函数内部根据请求方式的不同将请求参数放置在不同的位置  get 放在请求地址的后面、post 放在send方法中

                2.请求参数格式的问题

                    application/x-www-form-urlencoded  参数名称=参数值&参数名称=参数值   name=zhangsan&age=20

                    application/json    {name: 'zhangsan', age: 20}

 下面这段代码必须读懂

      function ajax(options) {
        // 存储的是默认参数
        var defaults = {
          type: "get",
          url: "",
          data: {},
          header: {
            "Content-Type": "application/x-www-form-urlencoded",
          },
          success: function () {},
          error: function () {},
        };
        // 使用options对象中的属性覆盖defaults对象中的属性
        Object.assign(defaults, options);

        // 创建ajax对象
        var xhr = new XMLHttpRequest();

        // 拼接请求参数的变量
        var params = "";
        // 循环用户传递进来的对象格式参数
        for (var attr in defaults.data) {
          // 将参数转换为字符串格式
          params += attr + "=" + defaults.data[attr] + "&";
        }
        // 将参数最后面的&截取掉
        // 将截取的结果重新赋值给params变量
        params = params.substr(0, params.length - 1);

        // 判断请求方式
        if (defaults.type == "get") {
          defaults.url = defaults.url + "?" + params;
        }
        /*
				{ name: 'zhangsan',
					age: 20 }

				name=zhangsan&age=20 
			 */
        // 配置ajax对象
        xhr.open(defaults.type, defaults.url);
        // 如果请求方式为post
        if (defaults.type == "post") {
          // 用户希望的向服务器端传递的请求参数的类型
          var contentType = defaults.header["Content-Type"];
          // 设置请求参数格式的类型
          xhr.setRequestHeader("Content-Type", contentType);
          // 判断用户希望的请求参数格式的类型
          // 如果类型为json
          if (contentType == "application/json") {
            // 向服务器端传递json数据格式的参数 JSON转换成json字符串
            xhr.send(JSON.stringify(defaults.data));
          } else {
            // 向服务器端传递普通类型的请求参数
            xhr.send(params);
          }
        } else {
          // 发送请求
          xhr.send();
        }
        // 监听xhr对象下面的onload事件
        // 当xhr对象接收完响应数据后触发
        xhr.onload = function () {
          // xhr.getResponseHeader()
          // 获取响应头中的数据 就是application/json还是text/html
          var contentType = xhr.getResponseHeader("Content-Type");
          // 服务器端返回的数据
          var responseText = xhr.responseText;

          // 如果响应类型中包含applicaition/json
          if (contentType.includes("application/json")) {
            // 将json字符串转换为json对象
            responseText = JSON.parse(responseText);
          }

          // 当http状态码等于200的时候
          if (xhr.status == 200) {
            // 请求成功 调用处理成功情况的函数
            defaults.success(responseText, xhr);
          } else {
            // 请求失败 调用处理失败情况的函数
            defaults.error(responseText, xhr);
          }
        };
      }

      ajax({
        type: "post",
        // 请求地址
        url: "http://localhost:3000/responseData",
        success: function (data) {
          console.log("这里是success函数");
          console.log(data);
        },
      });

3 客户端模板引擎

原本是服务器给你拼好传递给你,现在你客户端自己拼接数据和html

1 使用步骤

 注意:客户端的JavaScript不具备读取文件的能力,所以在客户端模板不是单独的文件,而是html文件中的代码片段,并且用script包裹。通过id=“tp1”区分模板。

但是<script>内部的编辑器默认将其作为js语法解析,可以在<script>添加属性,这样就可以将它作为html代码执行。

其实就是写一个模板    <script type="text/html" id="tpl">    </script>

然后把数据拼接模板template()

然后返回拼接好的返回到使用的地方

 <body>
    <div id="container"></div>
    <!-- 2.准备art-template模板 -->

    <script type="text/html" id="tpl">
      <h1>{{username}} {{age}}</h1>
    </script>
    //
    <script type="text/javascript">
      // 3.告诉模板引擎将那个数据和哪个模板进行拼接
      //    1) 模板id 2)数据 对象类型
      // 方法的返回值就是拼接好的html字符串
      var html = template("tpl", { username: "zhangsan", age: 30 });
      //  template返回<h1>zhangsan 30</h1>
      document.getElementById("container").innerHTML = html;
    </script>
  </body>

 2. 案例

思路逻辑4

 4. FormData 

4.1 FormData的作用

 注意:FormData只适用于post方式而不是get,应为要放在send()中。


	<script type="text/javascript">
		// 获取按钮
		var btn = document.getElementById('btn');
		// 获取表单
		var form = document.getElementById('form');
		// 为按钮添加点击事件
		btn.onclick = function () {
			// 将普通的html表单转换为表单对象
			var formData = new FormData(form);
			// 创建ajax对象
			var xhr = new XMLHttpRequest();
			// 对ajax对象进行配置
			xhr.open('post', 'http://localhost:3000/formData');
			// 发送ajax请求
			xhr.send(formData);
			// 监听xhr对象下面的onload事件
			xhr.onload = function () {
				// 对象http状态码进行判断
				if (xhr.status == 200) {
					console.log(xhr.responseText);
				}
			}
		}
	</script>

app.post('/formData', (req, res) => {
	// 创建formidable表单解析对象
	const form = new formidable.IncomingForm();
	// 解析客户端传递过来的FormData对象
	form.parse(req, (err, fields, files) => {
		res.send(fields);
	});
});

4.2 FormData对象的实例方法

                get('key') 获取表单对象属性的值

                set('key', 'value') 设置表单对象属性的值

                delete('key') 删除表单对象属性中的值

               append('key', 'value')追加属性以及值

注意:append和set都会追加值,因为set没有,设置后会追加,两个不同的区别就是在属性名已存在的前提下,set会覆盖原来的value,append会保留两个值,但是服务器端默认会接受最后一个value,如果是先set然后append,那么接受的就是append的value

        formData.set("username", "itcast");
        formData.append("username", "itheima");
        // 如果设置的表单属性不存在 将会创建这个表单属性
        formData.set("age", 100);
        // 删除用户输入的密码
        formData.delete("password");

4.3 FormData 二进制文件上传 同时实现文件上传图片即时预览

get不能用于文件上传!!!!!!!!

这个案例要好好看看

上传文件中使用事件对象 xhr.upload.onprogress = function (ev)可以记录进度条

        <div class="progress">
          //进度条
          <div class="progress-bar" style="width: 0%" id="bar">0%</div>
        </div>
       // 获取文件选择控件
      var file = document.getElementById("file");
      // 获取进度条元素
      var bar = document.getElementById("bar");
      // 获取图片容器
      var box = document.getElementById("box");
      // 为文件选择控件添加onchanges事件
      // 在用户选择文件时触发
      file.onchange = function () {
        // 创建空的formData表单对象
        var formData = new FormData();
        // 将用户选择的文件追加到formData表单对象中
        formData.append("attrName", this.files[0]);
        // 创建ajax对象
        var xhr = new XMLHttpRequest();
        // 对ajax对象进行配置
        xhr.open("post", "http://localhost:3000/upload");
        // 在文件上传的过程中持续触发
        xhr.upload.onprogress = function (ev) {
          // ev.loaded 文件已经上传了多少
          // ev.total  上传文件的总大小
          var result = (ev.loaded / ev.total) * 100 + "%";
          // 设置进度条的宽度
          bar.style.width = result;
          // 将百分比显示在进度条中
          bar.innerHTML = result;
        }};

app.post('/upload', (req, res) => {
	// 创建formidable表单解析对象
	const form = new formidable.IncomingForm();
	// 设置客户端上传文件的存储路径
	form.uploadDir = path.join(__dirname, 'public', 'uploads');
	// 保留上传文件的后缀名字
	form.keepExtensions = true;
	// 解析客户端传递过来的FormData对象
	form.parse(req, (err, fields, files) => {
		// 将客户端传递过来的文件地址响应到客户端
		res.send({
			path: files.attrName.path.split('public')[1]
		});
	});
});

app.post('/upload', (req, res) => {

    // 创建formidable表单解析对象

    const form = new formidable.IncomingForm();

    // 设置客户端上传文件的存储路径

    form.uploadDir = path.join(__dirname, 'public', 'uploads');

    // 保留上传文件的后缀名字

    form.keepExtensions = true;

    // 解析客户端传递过来的FormData对象

    form.parse(req, (err, fields, files) => {

        // 将客户端传递过来的文件地址响应到客户端

        res.send({

            path: files.attrName.path.split('public')[1] //返回服务器端电脑的硬盘地址 切割并且拿出来图片});})});

注意这个files.attrName.path.split('public')[1]。file是send最后一个参数,attrName是上传时候设置的名字,下面有一个path属性

split切割后,

5、同源政策

5.1 什么是同源

如果两个页面拥有相同的协议、域名和端口,那么这两个页面就属于一个源,其中一个不一样就是不同源。

5.2 同源政策的目的

5.3 使用JSONP解决同源限制的问题 

利用script代码可以向非同源服务器发送请求的特性, 加载完之后,就可以在客户端被调用,此时客户端要提前写好这个函数,而且是写在script前面。

jsonp全名就是在服务器端把json数据作为参数 返回给客户端定义的函数

 比如下面的是Jquery的js文件的不同源服务器访问,script标签的src属性不受同源政策的影响

<body>
	<script>
		function fn (data) {
			console.log('客户端的fn函数被调用了')
			console.log(data);
		}
	</script>
	<!-- 1.将非同源服务器端的请求地址写在script标签的src属性中 -->
	<script src="http://localhost:3001/test"></script>
</body>

app.get('/test', (req, res) => {
	const result = 'fn({name: "张三"})';
	res.send(result);
});

     <script src="http://localhost:3001/test"></script> 结束后,会调用一个函数,就是上面的,这个函数的调用是服务器端发起的

5.4 JSONP代码优化

5.4.1 动态创建

之前:请求在访问html页面时候发文

现在:设置成点击按钮再发送请求之类的(其实就是动态创建script标签)创建就会发送,发送请求后再把这个script标签删除。

5.4.2 函数名字优化

5.4.3 jsonp封装

 

把函数放进success,然后再定义为全局变函数。

注意:服务器端的res.jsonp方法,就是上面注释掉的

<body>
    <button id="btn1">点我发送请求</button>
    <button id="btn2">点我发送请求</button>
    <script type="text/javascript">
      // 获取按钮
      var btn1 = document.getElementById("btn1");
      var btn2 = document.getElementById("btn2");
      // 为按钮添加点击事件
      btn1.onclick = function () {
        jsonp({
          // 请求地址
          url: "http://localhost:3001/better",
          data: {
            name: "lisi",
            age: 30,
          },
          success: function (data) {
            //匿名函数!!!!没有名字
            console.log(123);
            console.log(data);
          },
        });
      };

      btn2.onclick = function () {
        jsonp({
          // 请求地址
          url: "http://localhost:3001/better",
          success: function (data) {
            console.log(456789);
            console.log(data);
          },
        });
      };

      function jsonp(options) {
        // 动态创建script标签
        var script = document.createElement("script");
        // 拼接字符串的变量
        var params = "";

        for (var attr in options.data) {
          params += "&" + attr + "=" + options.data[attr];
        }

        // myJsonp0124741  因为后面的会覆盖前面的函数名 所以要随机
        // 生成随机数.转换字符串.把“.”转换为空
        var fnName = "myJsonp" + Math.random().toString().replace(".", "");
        // 它已经不是一个全局函数了(因为写在了success中)
        // 我们要想办法将它变成全局函数,挂在Windows下
        window[fnName] = options.success;
        // 为script标签添加src属性
        script.src = options.url + "?callback=" + fnName + params;
        // 将script标签追加到页面中
        document.body.appendChild(script);
        // 为script标签添加onload事件
        script.onload = function () {
          document.body.removeChild(script);
        };
      }
    </script>
  </body>



app.get('/better', (req, res) => {
	// 接收客户端传递过来的函数的名称
	//const fnName = req.query.callback;
	// 将函数名称对应的函数调用代码返回给客户端
	//const data = JSON.stringify({name: "张三"});
	//const result = fnName + '('+ data +')';
	// setTimeout(() => {
	// 	res.send(result);
	// }, 1000)
	res.jsonp({name: 'lisi', age: 20});
});

5.4.4 jsonp获取腾讯天气的信息

使用了客户端的模板引擎   box.innerHTML = html; //模板的拼接结果

注意定义了处理日期的方法把2010091010改编成年月日的形式:

做法:定义处理日期的方法,方法在模板被调用。只需要在模板中暴露外部变量,这个变量可以是一个函数。      template.defaults.imports.dateFormat = dateFormat; 

最右边的dateFormat是一个函数

 <body>
    <div class="container">
      <table
        class="table table-striped table-hover"
        align="center"
        id="box"
      ></table>
    </div>
    <script src="/js/jsonp.js"></script>
    <script src="/js/template-web.js"></script>
    <script type="text/html" id="tpl">
      <tr>
        <th>时间</th>
        <th>温度</th>
        <th>天气</th>
        <th>风向</th>
        <th>风力</th>
      </tr>
      {{each info}}
      <tr>
        <td>{{dateFormat($value.update_time)}}</td>
        <td>{{$value.degree}}</td>
        <td>{{$value.weather}}</td>
        <td>{{$value.wind_direction}}</td>
        <td>{{$value.wind_power}}</td>
      </tr>
      {{/each}}
    </script>
    <script>
      // 获取table标签
      var box = document.getElementById("box");

      function dateFormat(date) {
        var year = date.substr(0, 4);
        var month = date.substr(4, 2);
        var day = date.substr(6, 2);
        var hour = date.substr(8, 2);
        var minute = date.substr(10, 2);
        var seconds = date.substr(12, 2);

        return (
          year +
          "年" +
          month +
          "月" +
          day +
          "日" +
          hour +
          "时" +
          minute +
          "分" +
          seconds +
          "秒"
        );
      }

      // 向模板中开放外部变量
      template.defaults.imports.dateFormat = dateFormat;

      // 向服务器端获取天气信息
      jsonp({
        url: "https://wis.qq.com/weather/common",
        data: {
          source: "pc",
          weather_type: "forecast_1h",
          // weather_type: 'forecast_1h|forecast_24h',
          province: "黑龙江省",
          city: "哈尔滨市",
        },
        success: function (data) {
          var html = template("tpl", { info: data.data.forecast_1h });
          box.innerHTML = html; //模板的拼接结果
        },
      });
    </script>
  </body>

5.5 CORS 跨域资源共享

 就是它允许浏览器向跨域服务器发Ajax请求,在服务器端配置。

 同意请求后,响应头会加进去点东西,就是一个白名单

// 拦截所有请求
app.use((req, res, next) => {
	// 1.允许哪些客户端访问我
	// * 代表允许所有的客户端访问我
	// 注意:如果跨域请求中涉及到cookie信息传递,值不可以为*号 比如是具体的域名信息
	res.header('Access-Control-Allow-Origin', 'http://localhost:3000')
	// 2.允许客户端使用哪些请求方法访问我
	res.header('Access-Control-Allow-Methods', 'get,post')
	// 允许客户端发送跨域请求时携带cookie信息
	res.header('Access-Control-Allow-Credentials', true);
	next();
});

因为不可能对所有的路由加进去res.header()这个方法,所以用express中间件先行拦截所有的请求。app.use()

5.6 访问非同源数据 服务器端解决方案

 A浏览器可以访问A 但是不能访问B服务器因为不同源,但是A服务器端可以访问B服务器端,所以让A服务器端当工具人。

使用request模块让服务器端来相互访问数据

const request = require('request');
app.get('/server', (req, res) => {
	request('http://localhost:3001/cross', (err, response, body) => {
		res.send(body);
	})
});

request()中的body就是B给A的响应,A再res.send(body)发给A浏览器端

5.7 cookie复习

相当于这个响应cooki就是服务器端发送给客户端的身份证,下次客户端发送请求会自动加上这个身份证,但是使用Ajax跨域时候,就不会自动加上这个身份证

withCredentials属性

 

 按理来说,登录成功后,点击检测用户登录状态 显示“处于未登录状态”因为

必须同时设置

res.header('Access-Control-Allow-Credentials', true);  服务器端的设置

xhr.withCredentials = true;   客户端的设置 

6、$Ajax()

 $("#btn").on("click", function () {
        $.ajax({
          // 请求方式
          type: "post",
          // 请求地址
          url: "/base",
          // 请求成功以后函数被调用
          success: function (response) {
            // response为服务器端返回的数据
            // 方法内部会自动将json字符串转换为json对象
            console.log(response);
          },
          // 请求失败以后函数被调用
          error: function (xhr) {
            console.log(xhr);
          },
        });
      });

如果文件地址和请求地址,域名协议端口相同,只用写一个/base就行

beforeSend()  方法,在发送之前做一点事情,再觉得是否发送请求。

      $("#btn").on("click", function () {
        $.ajax({
          // 请求方式
          type: "post",
          // 请求地址
          url: "/user",
          // 在请求发送之前调用 请求发送之前做一点事情
          beforeSend: function () {
            alert("请求不会被发送");
            // 请求不会被发送
            return false;
          },
          // 请求成功以后函数被调用
          success: function (response) {
            // response为服务器端返回的数据
            // 方法内部会自动将json字符串转换为json对象
            console.log(response);
          },
        });
      });

serialize()方法表单内容拼接成字符串类型的参数

      $("#form").on("submit", function () {
        // 将表单内容拼接成字符串类型的参数
        // var params = $('#form').serialize();
        // console.log(params)
        serializeObject($(this));
        return false;    });

最后的 return false;是为了防止表单自动提交

<script type="text/javascript">
      $("#form").on("submit", function () {
        // 将表单内容拼接成字符串类型的参数
        // var params = $('#form').serialize();
        // console.log(params)
        serializeObject($(this));
        return false;
      });

      // 将表单中用户输入的内容转换为对象类型
      function serializeObject(obj) {
        // 处理结果对象
        var result = {};
        // [{name: 'username', value: '用户输入的内容'}, 
        //   {name: 'password', value: '123456'}]
        var params = obj.serializeArray();

        // 循环数组 将数组转换为对象类型
        $.each(params, function (index, value) {
          result[value.name] = value.value;
        });
        // 将处理的结果返回到函数外部
        return result;
      }
    </script>

 $.each(params, function (index, value) {
          result[value.name] = value.value;  });

params是循环的参数,后面是回调函数。循环几次执行几次

index是索引,index0对应 {name: 'username', value: '用户输入的内容'}, 

                       index2对应 {name: 'password', value: '123456'}

6.1 $Ajax发送jsonp请求

    <script>
      function fn(response) {
        console.log(response);
      }
      $("#btn").on("click", function () {
        $.ajax({
          url: "/jsonp",
          // 向服务器端传递函数名字的参数名称
          jsonp: "cb",
          jsonpCallback: "fn",
          // 代表现在要发送的是jsonp请求
          dataType: "jsonp" /*,
					success: function (response) {
						console.log(response)
					}*/,
        });
      });
    </script>

app.get('/jsonp', (req, res) => {
	const cb = req.query.cb
	const data = cb+"({name: 'zhaoliu'})"
	res.send(data);
	// res.jsonp({
	// 	name: 'lisi',
	// 	age:50
	// })
});

6.2 $get()  $post()

function(response)就相当于success函数,第二个参数可以不写。

6.3 jQuery中的Ajax全局事件

全局事件:只要有Ajax发送,对应的全局事件就会被触发

.........

6. XML基础

 作用:传输和存储数据

app.get('/xml', (req, res) => {
	res.header('content-type', 'text/xml');  //这是一定要写的
	res.send('<message><title>消息标题</title><content>消息内容</content></message>')
});

 <script type="text/javascript">
      var btn = document.getElementById("btn");
      var container = document.getElementById("container");

      btn.onclick = function () {
        var xhr = new XMLHttpRequest();
        xhr.open("get", "/xml");
        xhr.send();
        xhr.onload = function () {
          // xhr.responseXML 获取服务器端返回的xml数据
          var xmlDocument = xhr.responseXML;
          var title = xmlDocument.getElementsByTagName("title")[0].innerHTML;
          container.innerHTML = title;
        };
      };
    </script>

7、GIt管理工具

只存储被修改的文件在 暂存区 然后提交到仓库

 

 查看分支

jinbo@harderfucker MINGW64 /d/software     Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (master)
$ git branch
* master

jinbo@harderfucker MINGW64 /d/software     Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (master)
$ git branch develop

jinbo@harderfucker MINGW64 /d/software     Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (master)
$ git branch
  develop
* master

jinbo@harderfucker MINGW64 /d/software     Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (master)
$ git checkout develop
Switched to branch 'develop'

jinbo@harderfucker MINGW64 /d/software     Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (develop)
$ git branch
* develop
  master

jinbo@harderfucker MINGW64 /d/software     Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (develop)
$ git add develop.html

jinbo@harderfucker MINGW64 /d/software     Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (develop)
$ git status
On branch develop
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   develop.html


jinbo@harderfucker MINGW64 /d/software     Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (develop)
$ git checkout master
Switched to branch 'master'
A       develop.html

jinbo@harderfucker MINGW64 /d/software     Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (master)
$ git checkout develop
Switched to branch 'develop'
A       develop.html

jinbo@harderfucker MINGW64 /d/software     Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (develop)
$ git commit -m 开发分支的第一次提交
[develop 75fd288] 开发分支的第一次提交
 1 file changed, 1 insertion(+)
 create mode 100644 develop.html

jinbo@harderfucker MINGW64 /d/software     Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (develop)
$ git checkout master
Switched to branch 'master'

jinbo@harderfucker MINGW64 /d/software     Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (master)
$ git checkout develop
Switched to branch 'develop'

jinbo@harderfucker MINGW64 /d/software     Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (develop)
$

 注意:

之前是必须提交,才能切换分支,现在是临时保存 git stash

 也就是你git stash后,可以切换分支,去干别的活,等你切换回原来分支后,可以git stash pop

8 Ajax中的模板引擎

由于服务器端返回的都是数组或者json对象,前端不能直接显示数组或者对象,必须要拼接进去html标签中,再通过DOM方法设置进去页面

不用模板引擎的问题:1、代码轮换 2、逻辑复杂

8.1 模板引擎的作用

模板渲染,    <script type="text/html" id="tpl">  type是text/html,这样的话就支持语法高亮

	<script src="js/template-web.js"></script>
	<script type="text/html" id="tpl">
		<div>
			<span>姓名:{{name}}</span>
			<span>年龄:{{age}}</span>
		</div>
	</script>

      // 这是告诉模板引擎将模板id为tpl的模板和data数据对象进行拼接
      var html = template("tpl", data);
/*       console.log(html);
	  <div>
        <span>姓名:{{name}}</span>
        <span>年龄:{{age}}</span>
      </div> */
      document.getElementById("container").innerHTML = html;

8.2 模板引擎的技巧

8.2.1 原文输出

在模板里面 @

      <div>
        <span>姓名:{{@ name}}</span>
        <span>年龄:{{age}}</span>
      </div>

     var data = {
        name: "<b>李四</b>",
        age: 30,
      };

        

8.2.2 条件判断

 

	<script type="text/html" id="tpl">
		<div>
			<span>姓名:{{@ name}}</span>
			<span>年龄:{{age}}</span>
		</div>
		{{if age > 18}}
			<div>年龄大于18</div>
		{{else}}
			<div>年龄小于18</div>
		{{/if}}
	</script>
		var data = {
			name: '<b>李四</b>',
			age: 25
		}

8.2.3 循环

each data中的data是数组  value指的是   {name: "张三",      age: 15,  }, value.name就是张三,value.age就是15

    <script type="text/html" id="tpl">
      <ul>
        {{each data}}
        <li>
          <span>姓名:{{$value.name}}</span>
          <span>年龄:{{$value.age}}</span>
        </li>
        {{/each}}
      </ul>
    </script> 
 var html = template("tpl", {
        data: [
          {
            name: "张三",
            age: 15,
          },
          {
            name: "李四",
            age: 20,
          },
          {
            name: "王五",
            age: 10,
          },
        ],
      });

8.2.4 导入模板变量

    <script type="text/html" id="tpl">
      
      <div>当前时间是:{{$imports.dateFormat(date)}}</div>
    </script>
    <script> 
        // 这是告诉模板引擎将模板id为tpl的模板和data数据对象进行拼接
        var html = template("tpl", {  date: new Date(),       });

        document.getElementById("container").innerHTML = html;

        function dateFormat(date) {
          console.log(date); //Tue Nov 08 2022 16:39:08 GMT+0800 (中国标准时间)
          return (
            date.getFullYear() +   "年" +    (date.getMonth() + 1) +
            "月" +   date.getDate() +      "日"
          );
        }
   
    </script>

但是有的时候会这样写,在外面包裹一层 window.onload() 当页面加载完成后执行函数体内部的代码,此时function dateFormat(date)不是全局的函数了, 但是可以导入到模板中,成为模板函数。

但是  template.defaults.imports.dateFormat = dateFormat;要放在函数定义的前面

<script>
      window.onload = function () {
        // 将方法导入到模板中
        template.defaults.imports.dateFormat = dateFormat;

        // 这是告诉模板引擎将模板id为tpl的模板和data数据对象进行拼接
        var html = template("tpl", {
          date: new Date(),
        });

        document.getElementById("container").innerHTML = html;

        function dateFormat(date) {
          console.log(date); //Tue Nov 08 2022 16:39:08 GMT+0800 (中国标准时间)
          return (
            date.getFullYear() +
            "年" +    (date.getMonth() + 1) +  "月" +  date.getDate() +    "日"  );
        }
      };
    </script>

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值