• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

49.AJAX、跨域

武飞扬头像
哥,你好猛
帮助1

Ajax

asynchronize javascript and xml:异步的javascript和xml。不是一门新技术,而是在原有的技术上进行整合。

作用:异步的发送请求,根据响应结果局部更新网页的技术。

优点:能够方便快速的给用户响应,提升用户体验。

缺点:不能使用网页的回退及收藏这样的功能。

Ajax核心:XMLHttpRequest

学新通

XMLHttpRequest的相关属性

学新通

XMLHttpRequest的相关方法

学新通

原生ajax实现

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <form>
      <table>
        <tr>
          <td>
            <input type="text" name="username" id="username">
          </td>
          <td id="info"></td>
        </tr>
      </table>
    </form>
  <script>
    document.getElementById("username").οnchange=function () {
        //1、创建xmlhttprequest
        var xhr = new XMLHttpRequest();
        //2、设置请求信息
        xhr.open("get","/user.do?method=checkUserName&username=" document.getElementById("username").value);
        //3、发送请求
        xhr.send(null);
        //4、注册回调函数
        xhr.onreadystatechange=function () {
          if (xhr.readyState == 4) {//请求成功结束
            if (xhr.status == 200) {//请求正常执行完成才有DOM操作的意义
              var text = xhr.responseText;
              document.getElementById("info").innerText=text
            }else if (xhr.status == 404) {
              document.getElementById("info").innerText="not found"
            }
          }
        }
    }
  </script>
  </body>
</html>

servlet

package com.woniuxy.servlet;

import com.woniuxy.commons.BaseServlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 使用BaseServlet时,
 * 如果接收的是ajax请求,则处理对应资源的servlet中的方法返回值只能是void
 * 如果接收的是非ajax请求,则方法的返回值可以是String,表示跳转的路径。
 */
@WebServlet("/user.do")
public class UserServlet extends BaseServlet {

    public void checkUserName(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        resp.setContentType("text/html;charset=utf-8");
        resp.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        if ("tom".equals(username)) {
            resp.getWriter().write("用户名已存在");
        }else{
            resp.getWriter().write("用户名不存在");
        }
    }
}

jquery的ajax

$.ajax

语法:

$.ajax(options)

options是一个javascript对象:{}

常用的属性:

contentType:指定请求中的内容类型

data:请求中附带的数据。

dataType:预期从服务端得到的数据类型

success:注册请求成功之后的回调函数

error:注册请求失败之后的回调函数

type:指定请求的提交方式

url:指定请求url

$.ajax.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript" src="https://blog.csdn.net/js/jquery-3.3.1.js"></script>
</head>
<body>
<form>
    <table>
        <tr>
            <td>
                <input type="text" name="username" id="username">
            </td>
            <td id="info"></td>
        </tr>
    </table>
</form>
<script>
    $(function () {
        $("#username").change(function () {
            $.ajax({
                url:"/user.do",
                data:{username:$(this).val(),method:"checkUserName"},
                type:"GET",
                dataType:"json",
                success:function (resp) {
                    console.log(resp)
                    $("#info").html(resp.username)
                }
            })
        })
    })
</script>
</body>
</html>

servlet

package com.woniuxy.servlet;

import com.alibaba.fastjson.JSONObject;
import com.woniuxy.commons.BaseServlet;
import com.woniuxy.model.User;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 使用BaseServlet时,
 * 如果接收的是ajax请求,则处理对应资源的servlet中的方法返回值只能是void
 * 如果接收的是非ajax请求,则方法的返回值可以是String,表示跳转的路径。
 */
@WebServlet("/user.do")
public class UserServlet extends BaseServlet {

    public void checkUserName(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        resp.setContentType("text/html;charset=utf-8");
        resp.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        User user = new User();
        user.setUsername("tom");
        user.setPassword("111");
        if ("tom".equals(username)) {
            //使用fastJson将对象转换为标准json字符串,浏览器看到标准的json字符串会自动将之转换为json对象
            resp.getWriter().write(new JSONObject().toJSONString(user));
        }else{
            resp.getWriter().write(new JSONObject().toJSONString(user));
        }
    }
}

注意:要使用fastJson,必须在项目中导入fastJson包

$.get(GET) $.post(POST)

是jquery对$.ajax方法进行了再次封装之后的结果,默认将请求方法作为方法来进行处理了。

语法:

$.get(url,data,funciton,dataType)
$.post(url,data,funciton,dataType)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript" src="https://blog.csdn.net/js/jquery-3.3.1.js"></script>
</head>
<body>
<form>
    <table>
        <tr>
            <td>
                <input type="text" name="username" id="username">
            </td>
            <td id="info"></td>
        </tr>
    </table>
</form>
<script>
    $(function () {
        $("#username").change(function () {
            $.get("/user.do",{username:$(this).val(),method:"checkUserName"},function (resp) {
                $("#info").html(resp.username)
            },"json")
        })
    })
</script>
</body>
</html>

$.getJSON

是对$.get方法的进一步封装,预期服务端返回的数据类型默认就是json。

语法:

$.getJSON(url,data,funciton)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript" src="https://blog.csdn.net/js/jquery-3.3.1.js"></script>
</head>
<body>
<form>
    <table>
        <tr>
            <td>
                <input type="text" name="username" id="username">
            </td>
            <td id="info"></td>
        </tr>
    </table>
</form>
<script>
    $(function () {
        $("#username").change(function () {
            $.getJSON("/user.do",{username:$(this).val(),method:"checkUserName"},function (resp) {
                $("#info").html(resp.username)
            })
        })
    })
</script>
</body>
</html>

load

jquery中用于加载其他页面内容的方法。

语法:

jquery元素.load("其他页面")

main.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form id="add">
        <input type="button" value="新增"/>
    </form>
    <form id="delete">
        <input type="button" value="删除"/>
    </form>
    <form id="update">
        <input type="button" value="修改"/>
    </form>
    <form id="find">
        <input type="button" value="查询"/>
    </form>
</body>
</html>

load.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript" src="https://blog.csdn.net/js/jquery-3.3.1.js"></script>
</head>
<body>
    <div id="content">

    </div>
    <script>
        $(function () {
            $("#content").load("main.jsp #add,#find")
        })
    </script>
</body>
</html>

跨域处理

什么是跨域?

注意:只有ajax请求才可能出现跨域问题!

基于安全的考虑,浏览器在发送ajax请求时,会进行同源检查,如果通不过同源检查,则会报出跨域访问的问题。

什么是同源?

浏览器在发出ajax请求时,会检查请求的页面与访问的后台服务端之间的协议、ip、端口是否相同,如果有其中之一不相同,则不满足同源策略,从而报出跨域访问的问题。

简单请求与复杂请求

简单请求:

请求方式只能是HEAD、GET、POST其中之一;

且HTTP请求头信息不超出以下几种字段:Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type。并且

Content-Type的值,只限于三个值: application/x-www-form-urlencoded、multipart/form-data、text/plain。

所有不满足简单请求要求的请求统称为复杂请求。

复杂请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为“预检”请求(preflight)。预检请求为OPTIONS请求,用于向服务器请求权限信息。预检请求被成功响应后,才会发出真实请求,携带真实数据。

注意:axios只能发复杂请求(vue中用于发送ajax的工具),因为axios默认请求的Content-type是application/json,因此其必须做跨域处理;jquery中的ajax可发简单请求,也可发复杂请求。

简单请求的处理:添加响应头。

//只能解决简单请求的跨域问题,不能解决复杂请求的跨域问题。
resp.setHeader("Access-Control-Allow-Origin","*");

复杂请求:使用第三方工具处理。

java-property-utils-1.9.1.jar、cors-filter-2.5.jar

配置过滤器

<!-- 跨域配置-->
    <filter>
        <filter-name>CORS</filter-name>
        <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
        <!--是否允许http请求跨域-->
        <init-param>
            <param-name>cors.allowGenericHttpRequests</param-name>
            <param-value>true</param-value>
        </init-param>
        <!--允许哪些源可以跨域-->
        <init-param>
            <param-name>cors.allowOrigin</param-name>
            <param-value>*</param-value>
        </init-param>
        <!--是否允许跨域访问子域名-->
        <init-param>
            <param-name>cors.allowSubdomains</param-name>
            <param-value>false</param-value>
        </init-param>
        <!--允许哪些http请求方式可以跨域-->
        <init-param>
            <param-name>cors.supportedMethods</param-name>
            <param-value>GET, HEAD, POST, OPTIONS</param-value>
        </init-param>
        <!--支持哪些请求头可以跨域-->
        <init-param>
            <param-name>cors.supportedHeaders</param-name>
            <param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified</param-value>
        </init-param>
        <!--        <init-param>-->
        <!--            <param-name>cors.exposedHeaders</param-name>-->
        <!--            &lt;!&ndash;这里可以添加一些自己的暴露Headers   &ndash;&gt;-->
        <!--            <param-value>X-Test-1, X-Test-2</param-value>-->
        <!--        </init-param>-->
        <!--允许跨域访问可以携带cookie-->
        <init-param>
            <param-name>cors.supportsCredentials</param-name>
            <param-value>true</param-value>
        </init-param>
        <!--设置跨域访问超时时间-->
        <init-param>
            <param-name>cors.maxAge</param-name>
            <param-value>3600</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>CORS</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script type="text/javascript" src="js/jquery-3.3.1.js"></script>
	</head>
	<body>
		<a href="http://127.0.0.1:8080/cors.do">测试普通请求</a>
		<hr>
		<input type="button" value="测试ajax请求" id="btn"/>
		<script>
			$(function(){
				$("#btn").click(function () {
					$.ajax({
                        //注释不放开,发送的是简单请求,放开,发送的是复杂请求
						/*beforeSend:function (xhr) {
							xhr.setRequestHeader("X-Requested-With","XMLHttpRequest")
						},*/
						url:"http://127.0.0.1:8080/cors.do",
						dataType:"text",
						type:"GET",
						success:function (resp) {
							alert(resp)
						}
					})
				})
			})
		</script>
	</body>
</html>

servlet

package com.woniuxy.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/cors.do")
public class TestCorsServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        resp.setCharacterEncoding("utf-8");
        //只能解决简单请求的跨域问题,不能解决复杂请求的跨域问题。
        resp.setHeader("Access-Control-Allow-Origin","*");
        System.out.println("访问成功");
        resp.getWriter().write("访问成功");
    }
}

蜗牛书城贯穿项目

静态页面开发

WoniuMall首页页面
WoniuMall商品详情页面

项目分析

WoniuMall需求分析
WoniuMall数据库设计

工程搭建

搭建项目的分层结构
在分层结构下开发数据访问层

WoniuMall后台管理

管理员登录
商品类别管理
商品管理
用户管理
订单管理
修改密码
管理员退出

系统前台

首页商品展示
商品详情展示
登陆,记住我
注册功能
添加商品到购物车
展示购物车信息
下订单
支付宝沙箱支付的使用
支付宝沙箱回调技术
使用支付宝沙箱完成下单功能

个人中心

JavaMail API
邮件注册激活
个人中心修改头像
查看个人中心
修改个人信息
新增收获地址
修改收货地址
设置默认收货地址
删除收货地址
订单列表
查看订单详情
修改密码

权限控制

管理员登录认证
个人用户登录认证

下开发数据访问层

WoniuMall后台管理

管理员登录
商品类别管理
商品管理
用户管理
订单管理
修改密码
管理员退出

系统前台

首页商品展示
商品详情展示
登陆,记住我
注册功能
添加商品到购物车
展示购物车信息
下订单
支付宝沙箱支付的使用
支付宝沙箱回调技术
使用支付宝沙箱完成下单功能

个人中心

JavaMail API
邮件注册激活
个人中心修改头像
查看个人中心
修改个人信息
新增收获地址
修改收货地址
设置默认收货地址
删除收货地址
订单列表
查看订单详情
修改密码

权限控制

管理员登录认证
个人用户登录认证

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgchgkj
系列文章
更多 icon
同类精品
更多 icon
继续加载