关于ajax:初见Ajax的认知与理解-一

43次阅读

共计 8283 个字符,预计需要花费 21 分钟才能阅读完成。

AJAX(Asynchronous JavaScript And XML 异步的 JavaScript 和 XML)


Ajax 的作用:
1、与服务器进行数据交换:通过 Ajax 能够给服务器发送申请,并获取服务器响应的数据。
2、应用 Ajax 和服务器进行通信,就能够应用 HTML 来替换 JSP 页面
3、Ajax 最重要的就是异步替换,能够在不从新加载整个页面的状况下,与服务器替换数据并更新局部网页的技术,比方,用户是否可校验。
同步:大伙循序渐进,老老实实的期待申请服务器,服务器解决,响应客户端这个过程,一步一步走。
异步:能够在期待申请服务器,服务器解决,响应客户端的过程中做些别的事件(用户感知不到这个过程,所有都悄咪咪的进行)。

那 Ajax 到底是怎么编写的呢?还是老规矩,给一个需要:通过 URL 传递数据,前端须要有两个输入框输出用户名和明码,用 Ajax 申请服务端。建一个数据库表(user),其中有两个字段,一个是 Name 字段一个是 Password 字段。提交,服务器接管,查询数据库。如果账号密码在数据库中存在,则提醒胜利,否则提醒失败。传参的形式必须是 post,参数不容许呈现在 url 上。

有了大抵流程,咱们就能开始入手啦!


1、在文本中填入数据点击提交
要校验用户的用户名和明码那必定得先输出用户名和明码,还须要提交这个数据,那咱们能够用 form 表单来实现这个性能。创立 HTML,命名为 ajax-demo.html:

<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
        <form id="form1" action="##"  method="post" accept-charset="UTF-8" onsubmit="return false">
            <p> 校验 </p>
            <input type="text" name="userName" id="txtUserName" placeholder="用户名"/>
            <input type="text" name="passWord" id="txtPassWord" placeholder="明码"/>
            <input type="submit"  value="提交" onclick="fun()"/>
        </form>
    </body>
</html>

表单是创立好了,那该怎么实现把数据提交到服务端上呢?能够看到我在表单里写了一个单击事件,执行 fun()办法(onclick=”fun()),这时就是咱们这篇的配角 Ajax 上场啦!
2、发送 Ajax 申请,提交 userName 和 passWord 到服务端
在应用 Ajax 之前,咱们先来理解一下 Ajax 的;两种申请形式:
GET 申请和 POST 申请。GET 申请和 POST 申请的用法很类似,都能够通过 URL 来传递参数。但 POST 申请还具备 requestBody,能够通过 setRequestHeader() 来增加 HTTP 头,通过 send 来传递参数。如需将申请发送到服务器,咱们应用 XMLHttpRequest 对象的 open() 和 send() 办法。

open(method,url,async):method:申请的类型;GET 或 POST,url:文件在服务器上的地位
,async:true(异步)或 false(同步)。

send(string):string:仅用于 POST 申请,因为 GET 申请没有 requestBody。

当然,想应用 open 和 send 办法之前,首先得创立一个 XMLHttpRequest 对象,因为这两种办法是 XMLHttpRequest 对象中的两种办法。
在理解完这两种申请之后,咱们就持续实现这个需要吧。在这里我就应用 POST 向 http://localhost:8080/addUser2 发送申请。

function fun(){const back = new XMLHttpRequest();
        let name = {"userName":form1.userName.value,"passWord":form1.passWord.value}
        userName="+name+"&&passWord="+psd;
        let userName = JSON.stringify(name);
        alert(userName);
        back.open("POST","http://localhost:8080/addUser2");
        //back.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 默认办法,固定格局
        back.setRequestHeader("Content-type","application/json;charset=UTF-8");// 能够发送 json 格局字符串
        back.send(userName);
    }

点击提交!

通过浏览器的开发者工具,咱们能看到游览器以及胜利的向服务端提交了一个 JSON 格局的数据(JSON.stringify()办法将 name 转换成了 JSON 格局),接下来就是着手筹备服务端的接管了。
3、服务端接管参数
浏览器向服务器发送了 post 申请,因为这次 POST 申请增加了标头,所以在 Servlet 中 request.getParameter()获取不了这个参数(如果没有增加标头,能够应用 request.getParameter()获取浏览器提交的数据)。
创立 DemoApplication。

public class DemoApplication {@RequestMapping("/addUser2")
    public People addUser2(HttpServletRequest request, HttpServletResponse response) throws IOException {//String userName = request.getParameter("username");
        //String passWord = request.getParameter("passWord");
        String contentType = request.getContentType();
        ServletInputStream is = request.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line=null;
        String result="";
        while((line=br.readLine())!=null){System.out.println(line); //{"username":"阿贾克斯","password":"123"}
            result  =result + "\n" +line;
        }
        System.out.println(result);
        return null;
      }
}

咱们再次提交数据,来查看服务端是否收到了来自浏览器的数据。
执行!

如同并没有合乎预期呀,难不成是浏览器没有胜利提交数据吗?咱们开启浏览器的开发者工具查看网络:

发现浏览器的确提交数据了,那为什么服务端没有收到来自浏览器提交的数据呢?
那咱们再查看一下控制台:

从“http://localhost:63342”拜访“http://localhost:8080”的 XMLHttpRequest 已被 CORS 策略阻止。这是什么起因?这就不得不说一下跨域问题了。
跨域,指的是浏览器不能执行其余网站的脚本。它是由浏览器的同源策略造成的,是浏览器施加的平安限度。
所谓同源是指,域名,协定,端口均雷同,只有有一个不同,就是跨域。
能够看到两个 URL 的端口并不相同(一个端口号是 63342,另一个端口号是 8080),所以发送了跨域申请,被阻止了。那该怎么顺利完成申请呢?那不如把 ajax-demo.html 写在 servlet 里吧,那端口号就统一了。

public class DemoApplication {@GetMapping("/hello1")
    public String hello1() {
        String str ;
        String htmlStr="";
        try {BufferedReader in = new BufferedReader(new FileReader("src/webapp/ajax-demo.html"));
            while ((str = in.readLine()) != null) {System.out.println(str);
                htmlStr  =htmlStr + "\n" +str;
            }
            System.out.print(htmlStr);
        } catch (IOException e) {System.out.print("谬误");
        }
        return htmlStr;
    }
    @RequestMapping("/addUser2")
    public People addUser2(HttpServletRequest request, HttpServletResponse response) throws IOException {//String userName = request.getParameter("username");
        //String passWord = request.getParameter("passWord");
        String contentType = request.getContentType();
        ServletInputStream is = request.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line=null;
        String result="";
        while((line=br.readLine())!=null){System.out.println(line); //{"username":"阿贾克斯","password":"123"}
            result  =result + "\n" +line;
        }
        System.out.println(result);
        return null;
      }
}

通过读取文件的形式将 ajax-demo.html 胜利的写在了 servlet 中,咱们再执行一次看看成果是否合乎预期。先执行程序,依据取得的 URL 在浏览器上输出。

这次再来试一试服务端能不能胜利接管浏览器提交的数据:

胜利!
既然接管到了浏览器提交的数据,那就开始执行下一步。
4、查询数据库并与服务端接管到的数据进行比拟,并且返回后果
首先创立数据库表 user,并插入相干数据数据:

create table user(username varchar(20) comment '用户',
    password  varchar(20) comment '明码'
) comment '账号表';

insert into user(username,password) values('阿贾克斯',123);

而后应用 MyBatis 动静代理来实现查询数据库,对于 MyBatis 配置方面这里就不过多赘述了,想理解的能够看看之前的文章:https://segmentfault.com/a/11…

首先创立 POJO 类:

package com.example.pojo;

public class User {
    private String userName;

    private String passWord;

    public String getUserName() {return userName;}

    public void setUserName(String userName) {this.userName = userName;}

    public String getPassWord() {return passWord;}

    public void setPassWord(String passWord) {this.passWord = passWord;}

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", passWord='" + passWord + '\'' +
                '}';
    }
}

而后增加 UserMapper 接口:

package com.example.mapper;

import com.example.pojo.User;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface UserMapper {User selectAll(@Param("userName")String username, @Param("passWord")String password);
}

创立 UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper">
    <select id="selectAll" resultType="User">
        select userName as username ,passWord as password from user where username = #{userName} and password=#{passWord};
    </select>
</mapper>

前置工作竣工,但在查询数据库之前,先得把服务端接管的 JSON 格局的数据提取到 Object 中, 再通过 Object 赋值给变量:
创立 People

package com.example;

import com.fasterxml.jackson.annotation.JsonView;

public class People {public interface WithoutPasswordView {};
    @JsonView(WithoutPasswordView.class)
    String userName ;
    @JsonView(WithoutPasswordView.class)
    String passWord ;
}

开始提取 JSON,查询数据库!

public class DemoApplication {@GetMapping("/hello1")
    public String hello1() {
        String str ;
        String htmlStr="";
        try {BufferedReader in = new BufferedReader(new FileReader("src/webapp/ajax-demo.html"));
            while ((str = in.readLine()) != null) {System.out.println(str);
                htmlStr  =htmlStr + "\n" +str;
            }
            System.out.print(htmlStr);
        } catch (IOException e) {System.out.print("谬误");
        }
        return htmlStr;
    }
    @RequestMapping("/addUser2")
    public People addUser2(HttpServletRequest request, HttpServletResponse response) throws IOException {//String userName = request.getParameter("username");
        //String passWord = request.getParameter("passWord");
        String contentType = request.getContentType();
        ServletInputStream is = request.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line=null;
        String result="";
        while((line=br.readLine())!=null){System.out.println(line); //{"username":"阿贾克斯","password":"123"}
            result  =result + "\n" +line;
        }
        System.out.println(result);
        // 提取 JSON 中的值
        ObjectMapper mapper = new ObjectMapper();
        People people = mapper.readValue(result,People.class);
        String userName = people.userName;
        String passWord = people.passWord;
        // 查询数据库
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //2. 获取 SqlSession 对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3. 获取 Mapper 接口的代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //4. 执行办法,数据库数据与 userName、passWord 做比拟
        User users =userMapper.selectAll(userName, passWord);
        System.out.println(users);
        // 开释资源
        sqlSession.close();
        // 如果 users 不为空,阐明服务端接管的与数据库的统一
        boolean flag = false;
        if (users != null) {flag = true;} else {// 阐明服务端接管的数据和数据库的不统一
            flag = false;
        }
        // 返回一个 Boolean
        response.getWriter().write("" + flag);
        return null;
      }
}

5、解决响应

function fun(){const back = new XMLHttpRequest();
        let name = {"userName":form1.userName.value,"passWord":form1.passWord.value}
        userName="+name+"&&passWord="+psd;
        let userName = JSON.stringify(name);
        // 解决响应
        back.onload = function(){
            // 判断 true、false
            if(this.responseText == "true"){
                // 明码账号正确
                alert("明码账号正确");
            }else{
                // 明码账号谬误
                 alert("明码账号谬误");
            }
        }
        alert(userName);
        back.open("POST","http://localhost:8080/addUser2");
        //back.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 默认办法,固定格局
        back.setRequestHeader("Content-type","application/json;charset=UTF-8");// 能够发送 json 格局字符串
        back.send(userName);
    }

到这所有的步骤都完结了,执行来看看成果:

合乎预期,胜利实现需要。

数据传递的大略流程:

下期内容

再增加一个新的需要:新增一个批改明码的接口,前端再减少一个批改明码的页面,申请和返回都应用 JSON,要求复用数据库连贯,解决读取 HTML 文件硬编码问题。

正文完
 0