AJAX的跨域问题使用设置响应头和JsonP的方式实现跨域------AJAX

131 篇文章 0 订阅
45 篇文章 0 订阅
AJAX在浏览器当中发送异步请求,请求之间是独立的,谁也不用等谁
类似于多线程并发,不会出现页面清空然后展示新的页面的效果
实现局部刷新(靠多种技术一起做到的,而不是一个技术叫ajax)
它是异步的(类似于多线程)
在AJAX的请求以及响应中完全依靠的是XMLHttpRequest对象
XMLHttpRequest对象的readyState属性记录了XMLHTTPREQUEST对象的状态
这个ReadyState属性的对应值有
0请求未初始化
1服务器连接已建立
2请求已收到
3正在处理请求
4请求已完成且响应已就绪
因此我们说当XMLHttpRequest对象的readyState属性变成4的时候
表示这个AJAX请求和响应已经全部完成
对于低版本的IE浏览器来说,ajax的get请求可能会走缓存,但是现代浏览器都没有这个问题了
什么是ajax的get请求缓存问题呢?
post请求不会被浏览器缓存,没有缓存问题
get请求直接从浏览器缓存获取资源,不需要从服务器重新加载资源,速度较快,用户体验好
缺点是无法实时获取最新浏览器资源
什么时候会走缓存,1get请求,2请求路径已经被浏览器缓存过了,路径没变化的情况会走缓存
如何解决低版本的ajax缓存问题
对于低版本的IE浏览器才有这样的缓存问题,可以采用URL时间戳来解决
我们需要给请求加一个时间戳
也可以使用随机数,或者随机数加上时间戳拼接到我们的请求内
a和B两个请求之间彼此不同步,不需要等待请求结束才能发送
同步和异步如何在代码上实现
假设一个ajax请求open的第三个参数是false,就表示这个请求不支持异步
也就是发送这个请求,会让其他请求的发送被暂缓,只有当我这个请求结束之后,其他的ajax请求才能发送
比方说,用户注册时,用户名邮箱密码都需要发送ajax请求校验
显然这个注册的ajax请求不能和校验的ajax请求异步,只能同步,避免提交非法数据
jsonp:json with padding(带填充的json)
不是一个真正的ajax请求,只不过可以完成Ajax的局部刷新效果
是一个类似ajax的效果
AJAX在浏览器当中发送异步请求,请求之间是独立的,谁也不用等谁
类似于多线程并发,不会出现页面清空然后展示新的页面的效果
实现局部刷新(靠多种技术一起做到的,而不是一个技术叫ajax)
它是异步的(类似于多线程)
在AJAX的请求以及响应中完全依靠的是XMLHttpRequest对象
XMLHttpRequest对象的readyState属性记录了XMLHTTPREQUEST对象的状态
这个ReadyState属性的对应值有
0请求未初始化
1服务器连接已建立
2请求已收到
3正在处理请求
4请求已完成且响应已就绪
因此我们说当XMLHttpRequest对象的readyState属性变成4的时候
表示这个AJAX请求和响应已经全部完成
对于低版本的IE浏览器来说,ajax的get请求可能会走缓存,但是现代浏览器都没有这个问题了
什么是ajax的get请求缓存问题呢?
post请求不会被浏览器缓存,没有缓存问题
get请求直接从浏览器缓存获取资源,不需要从服务器重新加载资源,速度较快,用户体验好
缺点是无法实时获取最新浏览器资源
什么时候会走缓存,1get请求,2请求路径已经被浏览器缓存过了,路径没变化的情况会走缓存
如何解决低版本的ajax缓存问题
对于低版本的IE浏览器才有这样的缓存问题,可以采用URL时间戳来解决
我们需要给请求加一个时间戳
也可以使用随机数,或者随机数加上时间戳拼接到我们的请求内
a和B两个请求之间彼此不同步,不需要等待请求结束才能发送
同步和异步如何在代码上实现
假设一个ajax请求open的第三个参数是false,就表示这个请求不支持异步
也就是发送这个请求,会让其他请求的发送被暂缓,只有当我这个请求结束之后,其他的ajax请求才能发送
比方说,用户注册时,用户名邮箱密码都需要发送ajax请求校验
显然这个注册的ajax请求不能和校验的ajax请求异步,只能同步,避免提交非法数据
jsonp:json with padding(带填充的json)
不是一个真正的ajax请求,只不过可以完成Ajax的局部刷新效果
是一个类似ajax的效果
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="http://localhost:8081/Test/1.js"></script>
</head>
<body>
<!--    超链接可以跨域-->
    <a href="http://localhost:8081/Test/Test.html">走,跨个域</a>
<!--form表单测试-->
<form action="http://localhost:8081/Test/reg" method="post">
    用户名:<input type="text" name="username">
    密码:<input type="password" name="password">
    <input type="submit" value="注册">
</form>
<script type="text/javascript" src="JS/jQuery-1.0.0.js">
</script>
<script type="text/javascript">
    $(function(){
       $("#AjaxTrans").click(function(){
           let ajax = new XMLHttpRequest();
           ajax.onreadystatechange = function()
           {
               // 默认情况下,ajax发出跨域请求会有以下错误
//1.html:1  Access to XMLHttpRequest at 'http://localhost:8081/Test/hello'
//from origin 'http://localhost:8080' has been blocked by CORS policy:
//No 'Access-Control-Allow-Origin' header is present on the requested resource.
               //CORS策略阻止,这个ajax请求被同源策略阻止了
               //两个站点共享了xmlHttpRequest对象
               //因为页面的XmlHttpRequest对象不可以共享,一旦共享,对方就可以拿到我们的responseHtml
               //同源策略是浏览器的安全策略
               //协议,端口号,域名一致才是同源
               //同源才可以共享,不同源任何信息都不能共享
               //在我们此前所有的跳转和发送请求中,本质都是通过浏览器地址栏跳转来实现的,他们都没有安全问题
               //为什么ajax不行,因为只有它发送请求依靠的是我们浏览器内置的XmlHttpRequest对象
               //当我们A发送AJAX请求到B站点的时候,相当于我们两个站点共享了XmlHttpRequest对象
               //两个站点就都可以获取彼此的response信息,用户的宝贵信息就泄露了
               if (ajax.readyState === 4) {
                   if (ajax.status === 200) {
                       $("#MyDiv").html(ajax.responseText);
                   }
                   else
                   {
                       alert(ajax.status);
                   }
               }
           }
           ajax.open("GET","http://localhost:8081/Test/hello",true);
           ajax.send();
       });
    });
</script>
<button onclick="window.location.href='http://localhost:8081/Test/Test.html'">跳页面</button>
<button id="AjaxTrans">ajax跨域请求</button>
<div id="MyDiv"></div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="http://localhost:8081/Test/1.js"></script>
</head>
<body>
<!--    超链接可以跨域-->
    <a href="http://localhost:8081/Test/Test.html">走,跨个域</a>
<!--form表单测试-->
<form action="http://localhost:8081/Test/reg" method="post">
    用户名:<input type="text" name="username">
    密码:<input type="password" name="password">
    <input type="submit" value="注册">
</form>
<script type="text/javascript" src="JS/jQuery-1.0.0.js">
</script>
<script type="text/javascript">
    $(function(){
       $("#AjaxTrans").click(function(){
           let ajax = new XMLHttpRequest();
           ajax.onreadystatechange = function()
           {
               // 默认情况下,ajax发出跨域请求会有以下错误
//1.html:1  Access to XMLHttpRequest at 'http://localhost:8081/Test/hello'
//from origin 'http://localhost:8080' has been blocked by CORS policy:
//No 'Access-Control-Allow-Origin' header is present on the requested resource.
               //CORS策略阻止,这个ajax请求被同源策略阻止了
               //两个站点共享了xmlHttpRequest对象
               //因为页面的XmlHttpRequest对象不可以共享,一旦共享,对方就可以拿到我们的responseHtml
               //同源策略是浏览器的安全策略
               //协议,端口号,域名一致才是同源
               //同源才可以共享,不同源任何信息都不能共享
               //在我们此前所有的跳转和发送请求中,本质都是通过浏览器地址栏跳转来实现的,他们都没有安全问题
               //为什么ajax不行,因为只有它发送请求依靠的是我们浏览器内置的XmlHttpRequest对象
               //当我们A发送AJAX请求到B站点的时候,相当于我们两个站点共享了XmlHttpRequest对象
               //两个站点就都可以获取彼此的response信息,用户的宝贵信息就泄露了
               if (ajax.readyState === 4) {
                   if (ajax.status === 200) {
                       $("#MyDiv").html(ajax.responseText);
                   }
                   else
                   {
                       alert(ajax.status);
                   }
               }
           }
           ajax.open("GET","http://localhost:8081/Test/hello",true);
           ajax.send();
       });
    });
</script>
<button οnclick="window.location.href='http://localhost:8081/Test/Test.html'">跳页面</button>
<button id="AjaxTrans">ajax跨域请求</button>
<div id="MyDiv"></div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script type="text/javascript">
    //这里并不是后端的java代码调用了前端的js代码
    //实际上后端只负责响应一串字符串回去而已,调用JS代码的还是前端的浏览器
    function sayHello(json)
    {
        console.log("Hello" + json.name);
    }
    function sum(a,b)
    {
        console.log(a + b);
    }
</script>
    <script type="text/javascript" src="http://localhost:8081/Test/jsonP1?fun=sum">
        // script标签是可以跨域的,src属性可以是一个xxx.js文件
        //超链接不能,因为超链接会跳转页面,不能实现页面局部刷新效果
    </script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script type="text/javascript">
    //这里并不是后端的java代码调用了前端的js代码
    //实际上后端只负责响应一串字符串回去而已,调用JS代码的还是前端的浏览器
    function sayHello(json)
    {
        console.log("Hello" + json.name);
    }
    function sum(a,b)
    {
        console.log(a + b);
    }
</script>
    <script type="text/javascript" src="http://localhost:8081/Test/jsonP1?fun=sum">
        // script标签是可以跨域的,src属性可以是一个xxx.js文件
        //超链接不能,因为超链接会跳转页面,不能实现页面局部刷新效果
    </script>
</body>
</html>
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/jsonP1")
public class jsonP1 extends HttpServlet
{
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
//        jsonP跨域的时候只支持get请求,因为我们写src本质就是一个get请求的传递
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        //如果是输出前端代码呢?
//        out.println("alert(123);");
//        out.println("sayHello();");
        String fun = request.getParameter("fun");
//        out.println(fun + "({\"name\" : \"Jack\"});");
        out.println(fun + "(5,6);");
    }
}
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/jsonP1")
public class jsonP1 extends HttpServlet
{
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
//        jsonP跨域的时候只支持get请求,因为我们写src本质就是一个get请求的传递
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        //如果是输出前端代码呢?
//        out.println("alert(123);");
//        out.println("sayHello();");
        String fun = request.getParameter("fun");
//        out.println(fun + "({\"name\" : \"Jack\"});");
        out.println(fun + "(5,6);");
    }
}
// 封装一个函数,通过这个函数就可以获取页面中的元素了
function JQuery(selector)//可能时#id或者.class这样的类选择器
{
    if(typeof selector === "string")
    {
        // 设计思路根据CSS语法
        if (selector.charAt(0) === "#")
        {
            // 根据ID获取元素
            //这个是全局对象,是根据我们的ID获取的dom对象
            IE = document.getElementById(selector.substring(1));
            //返回JQuery对象,这个有html方法
            return new JQuery();
        }
    }
    if(typeof selector === "function")
    {
        window.onload = selector;
    }
    //定义一个HTML方法
    this.html = function(htmlStr)
    {
        IE.innerHTML = htmlStr;
    }
    //定义一个click函数代替onclick方法
    this.click = function(fun)
    {
        IE.onclick = fun;
    }
    //下拉栏变化
    this.change = function(fun)
    {
        IE.onchange = fun;
    }
    //由此可知
    this.val = function(value)
    {
        if(value === undefined)
        {
            return IE.value;
        }
        else
        {
            IE.value = value;
        }
    }
    //定义一个静态方法用来发送AJAX请求
    //JS中的静态方法也还是需要有这个对象的
    //传递参数如下,1.传递的数据2.请求方法3.url地址4.是否异步执行
    JQuery.ajax = function(JsonArgs)
    {
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function()
        {
            if (this.readyState === 4)
            {
                if (this.status === 200)
                {
                    var JsonObj = JSON.parse(this.responseText);
                    JsonArgs.success(JsonObj);
                }
                else
                {
                    alert(this.status);
                }
            }
        }
        if(JsonArgs.type.toUpperCase() === "POST")
        {
            xhr.open("POST",JsonArgs.url,JsonArgs.async);
            xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
            xhr.send(JsonArgs.data);
        }
        if(JsonArgs.type.toUpperCase() === "GET")
        {
            JsonArgs.type = "GET";
            xhr.open("GET",JsonArgs.url+"?"+JsonArgs.data,JsonArgs.async);
            xhr.send();
        }
    }
}
$ = JQuery;
//执行这个的目的是为了让静态方法能生效
new JQuery();
// 封装一个函数,通过这个函数就可以获取页面中的元素了
function JQuery(selector)//可能时#id或者.class这样的类选择器
{
    if(typeof selector === "string")
    {
        // 设计思路根据CSS语法
        if (selector.charAt(0) === "#")
        {
            // 根据ID获取元素
            //这个是全局对象,是根据我们的ID获取的dom对象
            IE = document.getElementById(selector.substring(1));
            //返回JQuery对象,这个有html方法
            return new JQuery();
        }
    }
    if(typeof selector === "function")
    {
        window.onload = selector;
    }
    //定义一个HTML方法
    this.html = function(htmlStr)
    {
        IE.innerHTML = htmlStr;
    }
    //定义一个click函数代替onclick方法
    this.click = function(fun)
    {
        IE.onclick = fun;
    }
    //下拉栏变化
    this.change = function(fun)
    {
        IE.onchange = fun;
    }
    //由此可知
    this.val = function(value)
    {
        if(value === undefined)
        {
            return IE.value;
        }
        else
        {
            IE.value = value;
        }
    }
    //定义一个静态方法用来发送AJAX请求
    //JS中的静态方法也还是需要有这个对象的
    //传递参数如下,1.传递的数据2.请求方法3.url地址4.是否异步执行
    JQuery.ajax = function(JsonArgs)
    {
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function()
        {
            if (this.readyState === 4)
            {
                if (this.status === 200)
                {
                    var JsonObj = JSON.parse(this.responseText);
                    JsonArgs.success(JsonObj);
                }
                else
                {
                    alert(this.status);
                }
            }
        }
        if(JsonArgs.type.toUpperCase() === "POST")
        {
            xhr.open("POST",JsonArgs.url,JsonArgs.async);
            xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
            xhr.send(JsonArgs.data);
        }
        if(JsonArgs.type.toUpperCase() === "GET")
        {
            JsonArgs.type = "GET";
            xhr.open("GET",JsonArgs.url+"?"+JsonArgs.data,JsonArgs.async);
            xhr.send();
        }
    }
}
$ = JQuery;
//执行这个的目的是为了让静态方法能生效
new JQuery();
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

@WebServlet("/hello")
public class Hello extends HttpServlet
{
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置响应头
        response.setHeader("Access-Control-Allow-Origin","http://localhost:8080");
        //跨域访问的资源允许访问,设置响应头的方式原理是
        response.getWriter().println("Halla Ajax");
    }
}
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

@WebServlet("/hello")
public class Hello extends HttpServlet
{
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置响应头
        response.setHeader("Access-Control-Allow-Origin","http://localhost:8080");
        //跨域访问的资源允许访问,设置响应头的方式原理是
        response.getWriter().println("Halla Ajax");
    }
}
alert("我是B应用的文件");
alert("我是B应用的文件");
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/reg")
public class Test extends HttpServlet
{
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        PrintWriter out = response.getWriter();
        out.println(username+password);
    }
}
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/reg")
public class Test extends HttpServlet
{
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        PrintWriter out = response.getWriter();
        out.println(username+password);
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>欢迎来到测试应用</h1>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>欢迎来到测试应用</h1>
</body>
</html>
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值