$.ajax与同源策略

发布时间:2024年01月24日

1.jQuery中的ajax请求

  • 学习Jquery中的ajax,我们借助官方文档

  • $.ajax(url,[settings]) | jQuery API 3.2 中文文档 | jQuery API 在线手册

  • 使用$.ajax()方法完成图书案例

  • <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <style>
          .container {
            width: 350px;
            min-height: 150px;
            background: pink;
            margin: 50px auto;
          }
        </style>
      </head>
    
      <body>
        <!-- 需求分析:给出指定的图书编码,通过发送get请求的方式,获取到该图书的相关信息,并渲染页面 -->
    
        <div class="container">
          <span>图书编码:</span>
          <input type="text" id="code" />
          <input type="button" value="查询" id="btn" />
          <div id="info"></div>
        </div>
        <script src="jquery.js"></script>
        <script>
          $(function () {
            $('#btn').click(function () {
              $.ajax({
                type: 'get',
                url: 'http://localhost:3333/get/book',
                data: {
                  code: $('#code').val()
                },
                dataType: 'json',
                success(data) {
                  // console.log(data);
                  if (data.error != 0) {
                    var htmlStr = `<ul>`;
                    $.each(data, (key, val) => {
                      htmlStr += `<li>${key}:${val}</li>`;
                    });
                    htmlStr += '</ul>';
                    $('#info').html(htmlStr);
                  } else {
                    $('#info').html(data.msg);
                  }
                }
              });
            });
          });
        </script>
      </body>
    </html>

2.表单的相关事件

2.1form标签的属性

action,method,target,enctype

代码演示:相关属性 
 <form action="submit.html" target="_self" method="get" enctype="multipart/form-data">
    <label>
      <p>用户名: <input type="text" name="username">
      </p>
    </label>
    <label>
      <p>密码: <input type="password" name="password">
      </p>
      <button>提交数据</button>
    </label>
  </form>

2.2监听表单的提交事件与阻止表单提交跳转的默认行为

原生方法

<script>
  var form = document.querySelector("#form")
  form.addEventListener("submit", function (e) {
    console.log("提交了数据");
    e.preventDefault()
  })
</script>

jQuery中的方法

<script>
  $(function () {
    // $("#form").submit(function (e) {
    //   console.log("提交了数据");
    //   e.preventDefault()
    // })
    $("#form").on('submit', function (e) {
      console.log("提交了数据");
      e.preventDefault()
    })
  })
</script>

2.3 获取以及清空表单中的数据

对应UI结构如下

 <form id="form" action="submit.html" method="post" target="_self" enctype="multipart/form-data">
    <label>
      用户名:
      <input type="text" name="username" id="username">
    </label>
    <label>
      密码:
      <input type="password" name="password" id="password">
    </label>
    <input type="radio" name="gender" value="男">男
    <input type="radio" name="gender" value="女">女
    <input type="radio" name="gender">
    <input type="checkbox" value="游泳" name="checkbox" class="hobby">游泳
    <input type="checkbox" value="看书" name="checkbox" class="hobby">看书
    <input type="checkbox" value="敲代码" name="checkbox" class="hobby">敲代码
    <select name="city" id="">
      <option value="请选择">请选择</option>
      <option value="帝都">帝都</option>
      <option value="魔都">魔都</option>
      <option value="酆都">酆都</option>
      <option value="妖都">妖都</option>
    </select>
    <button>提交</button>
  </form>
  • 使用serialize()函数,此方法必须给需要获取的form的表单里面的元素添加name值

// 2.使用serialize()函数,此方法必须给需要获取的form的表单里面的元素添加name值
      var data = $("#form").serialize()
      console.log(data);
      返回结果是这样:
      username=zhangsan&password=123456&checkbox=%E6%B8%B8%E6%B3%B3&checkbox=%E7%9C%8B%E4%B9%A6&checkbox=%E6%95%B2%E4%BB%A3%E7%A0%81
  • 清空表单数据.reset()方法可以清空表单的值,但是这个方法是一个js方法,需要将使用对象进行转换。

 $(function () {
    $("#form").on('submit', function (e) {
      e.preventDefault()
      var data = $("#form").serialize()
      console.log(data);
      $("#form").get(0).reset()
    })
  })

2.4 使用submit按钮提交与普通按钮click提交的区别

  • 表单提交,是formData格式,常用于图片,文件等资源。可以在提交验证时阻止默认行为。按钮提交用ajax对请求数据格式进行封装。

  • form表单能直接通过action属性设置提交地址,没有跨域问题,如果你直接用click提交那就是ajax,无法跨域的

3.Ajax同源策略与跨域

3.1 Ajax的请求限制

  • Ajax 只能向自己的服务器发送请求。比如现在有一个A网站、有一个B网站,A网站中的 HTML 文件只能向A网站服务器中发送 Ajax 请求,B网站中的 HTML 文件只能向 B 网站中发送 Ajax 请求,但是 A 网站是不能向 B 网站发送 Ajax请求的,同理,B 网站也不能向 A 网站发送 Ajax请求

3.2 同源策略

example123.com?-?该网站正在出售!?-?example123 资源和信息。域名不同
example123.com?-?该网站正在出售!?-?example123 资源和信息。协议不同
http://www.example123.com:8080/detail.html端口不同
http://api.example123.com:8080/detail.html域名、端口不同
example123.com?-?该网站正在出售!?-?example123 资源和信息。协议、域名不同
https://www.example123.com:8080/detail.html端口、协议不同
  • 同源策略主要为了保证浏览器的安全性

同源政策是为了保证用户信息的安全,防止恶意的网站窃取数据。最初的同源政策是指A网站在客户端设置的 ? Cookie,B网站是不能访可的。

随着互联网的发展,同源政策也越来越严格,在不同源的情况下,其中有一项规定就是无法向非同源地址发送 ? Ajax请求,如果请求,浏览器就会报错。

在同源策略下,浏览器不允许Ajax跨域获取服务器数据

  • 代码验证同源策略

准备2台服务器,serve1与serve2,其中1号服务器监听3007端口,2号服务器监听3008端口

3.3 跨域解决方案 相对安全

jsonp

document.domain+iframe

location.hash + iframe

window.name + iframe

window.postMessage

flash等第三方插件

cors

3.4.使用jsonp解决同源限制问题

  • 实际上就是绕过浏览器的同源限制,向非同源服务器发送请求

  • jsonp是 json with padding的缩写,它不属于Ajax请求,但它可以模拟Ajax请求。

代码演示

  <script type="text/javascript">
        // 要写在函调调用之前
        function fn(data) {
            console.log("客户端的fn函数被调用了")
            console.log(data)
        }
    </script>
    <script type="text/javascript" src="http://localhost:3008/test02"></script>


  后端返回一个函数名+() 括号中放点参数
  
  fn( {a :10})

3.5 .jsonp优化

  • 虽然我们已经实现了,jsonp请求,但是这个请求是在页面一加载的时候就实现的,我们希望可以将请求变成动态形式,比如,当我们点击一个按钮的时候,才发送jsonp请求,我们的做法如下:

  • 将 script请求的发送变成动态请求。

  • <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <script>
            function fn(data) {
                console.log(data.username, data.password);
                // fn({"username":"zhangsan","password":"123456"})
            }
        </script>
    </head>
    
    <body>
        <button id="btn">点击发送请求</button>
        <script type="text/javascript">
            window.onload = function () {
                var btn = document.getElementById("btn")
                btn.onclick = function () {
                    var script = document.createElement('script');
                    script.src = 'http://localhost:3008/test03'
                    var head = document.getElementsByTagName('head')[0];
                    head.appendChild(script);
                    //监听script标签,并删除
                    script.onload = function () {
                        head.removeChild(script)
                    }
                }
            }
        </script>
    </body>
  • 客户端需要将函数名称传递到服务器端

  • var btn = document.getElementById("btn")
                btn.onclick = function () {
                    var script = document.createElement('script');
                    script.src = 'http://localhost:3008/test04?callback=fn'
                    var head = document.getElementsByTagName('head')[0];
                    head.appendChild(script);
                    //监听script标签,并删除
                    script.onload = function () {
                        head.removeChild(script)
                    }

3.6 jsonp的本质?

jsonp的本质就是动态创建script标签,然后通过src属性向服务端发送跨域请求
?通过响应的内容来调用咱们事先定义好的函数方法,从而通过函数的参数,得到服务端响应的数据。
?注意,客户端得到的有一个函数调用
?服务器响应的内容是【函数调用】 所谓的函数调用就是函数名字加括号,中间存点参数fn(实参)

3.7.jQuery对jsonp的支持

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script type="text/javascript" src="./jquery.js"></script>
    <script type="text/javascript">
        $(function () {
            $("#btn").click(function () {
                $.ajax({
                    type: "get",
                    url: "http://localhost:3008/test05",
                    dataType: 'jsonp', //指定类型
                    jsonpCallback: "hello", //指定函数名字
                    success: function (data) {
                        console.log(data);
                    },
                    error: function () {
                        console.log("failure");
                    }
                })
            });
        });
    </script>
</head>

<body>
    <input type="button" value="点击" id="btn">
</body>

4.0 防抖与节流

4. 1 什么是防抖?

image-20230422234546692

4.2 应用:

用户在输入框中连续输入一串字符时,可以通过防抖策略,只在输入完后,才执行查询的请求,这样可以有效减 少请求次数,节约请求资源;

1. ?var timer = null // 1.定义防抖标识
2. ?定义防抖函数
3. ?触发keyup事件时,立即清timer

4.3 节流

节流策略( throttle),顾名思义,可以减少段时间内事件的触发频率

image-20230422234949011

4.4 节流应用场景

①鼠标连续不断地触发某事件(如点击),只在单位时间内只触发一次; ②懒加载时要监听计算动条的位置.但不必每次滑动都觖发,可以降低计算的频率,而不必去浪费CPU资源:

4.5 节流阀的概念

  • 高铁卫生间是否被占用,由红绿灯控制,红灯表示被占用,绿灯表示可使用。

  • 假设每个人上卫生间都需要花费5分钟,则五分钟之内,被占用的卫生间无法被其他人使用

  • 上一个人使用完毕后,需要将红灯重置为绿灯,表示下—个人可以使用卫生间

  • 下—个人在上卫生间之前,需要先判断控制灯是否为绿色,来知晓能否上卫生间。

  • 节流阀为空,表示可以执行下次操作;不为空,表示不能执行下次操作。

  • 当前操作执行完,必须将节流阀重置为空,表示可以执行下次操作了。

  • 每次执行操作前,必须先判断节流阀是否为空

4.6 总结防抖和节流的区别

  • 防抖:如果事件被频繁触发,防抖能保证只有最后一次触发生效!前面N多次的触发都会被忽略!

  • 节流:如果事件被频繁触发,节流能够减少事件触发的频率,因此,节流是有选择性地执行部分事件!

5.cors跨域资源共享

  • CORS:全称为 Cross-origin resource sharing,即跨域资源共亨,它允許浏览器向跨域服务器发送Ajax请求克服了Ajax只能同源使用的限制。

  • // // 设置允许跨域访问该服务
    app.all('*', function (req, res, next) {
    ? res.header("Access-Control-Allow-Origin", "*");
    ? res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
    ? res.header("Access-Control-Allow-Headers", "X-Requested-With,Content-Type,mytoken");
    ? next();
    });

6.访问非同源数据,服务器端解决方案

  • 原理:同源政策是浏览器给予Ajax技术的限制,服务器端是不存在同源政策跟制

  • 我们可以先让自己的服务器去访问服务器端数据,当我们需要数据时,在去请求自己的服务器,规避了ajax直接请求服务器。此方法需要使用request模块。

7.本地存储

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button>存数据</button>
    <button>取数据</button>
    <button>删除数据</button>
    <button>清空数据</button>
    <br>
    <input type="text" id="username">

    <script>
        var username = document.getElementById("username")
        var btns = document.querySelectorAll("button")
    // 存用户名 username data
    // sessionStorage 
    // 注意事项: 
    // 1.同一个域 
    // 2.在浏览器不关闭的情况下使用
    // 3.可存储大小 大概 在5M左右


    // localStorage
    // 注意事项: 
    // 1.同一个域 
    // 2.在浏览器关闭的情况同样可以继续使用
    // 3.可存储大小 大概 在20M左右

        btns[0].onclick = function () {
            var data = username.value
            localStorage.setItem("username",data)
        }

          //    取用户名
        btns[1].onclick = function () {

           var data =  localStorage.getItem("username")
           console.log(data);
        }

          //    删除用户名
        btns[2].onclick = function () {
        localStorage.removeItem("username")
        }

        // 全部清空
        btns[3].onclick = function () {
            localStorage.clear();
        }
    </script>


</body>
</html>

文章来源:https://blog.csdn.net/Gao_xu_sheng/article/details/135573452
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。