Blogger Information
Blog 28
fans 0
comment 0
visits 29993
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
json、ajax和跨域请求jsonp细说
G
Original
1165 people have browsed it

json

  • 什么是json:json 是 js 的对象表示法,是通用的跨编程语言的轻量级数据交换/传输/存储格式
    • jsonjs的区别
      1. json 不是值,不能赋值给变量,没有变量
      2. json 不是 js 语句,没有分号
      3. json 中的属性必须加双引号, 哪怕是合法属性名
  1. // JS对象:
  2. const user = {
  3. name:"GGG",
  4. email = "12345679@youyou6.net",
  5. age = 20,
  6. };
  1. // JS对象表示法:json数据:
  2. {
  3. "name" = "GGG",
  4. "email" = "123456798@youyou6.net,
  5. "age" = 20 //最后一项不能有逗号(json不能写注释,这里是为了说明)
  6. } // 结束不能有分号;
  1. - `json`的数据类型:
  2. 1. 数值
  3. 2. 布尔值
  4. 3. 字符串
  5. 4. null
  6. 没有underfined
  7. 5. 复合类型:对象和数组

json 只支持字面量

  1. let user = `{
  2. "name": "GGG",
  3. "email": "123456@youyou6.net",
  4. "age": "20"
  5. }`;

PS:

  1. json 不能有注释
  2. js 字符串需要解析为 js 对象才可以用个到浏览器之中。

JSON.parse(jsonStr)

通过 JSON.parse()可以将一个 json 字符串数据转换为一个 JS 对象,方便调用和数据的处理。

  1. // 设置一个json字符串(字面量字符串)
  2. let user = `{
  3. "name": "GGG",
  4. "email": "123456@youyou6.net",
  5. "age": "20"
  6. }`;
  7. let num = `{
  8. "id" : 1,
  9. "price" : 55,
  10. "num" : "暂无存货"
  11. }`;

语法:变量 = JSON.parse(json字符串) =>将 json 模板字面量转化为一个对象object

  1. // 通过JSON.parse接口将json字符串转换为js对象,方便数据调用和处理
  2. const obj = JSON.parse(user);
  3. console.log(obj);
  4. const pac = JSON.parse(num);
  5. console.log(pac);
  6. console.log(typeof pac);


JSON.stringify

作用:将 JS 对象/数组/属性/值等转换为 Json 字符串,方便 json 存储和使用。
变量 = JSON.stringify(对象/值/数组等)
工作方法:

演示:

  1. const produce = {
  2. name: "手机",
  3. price: 88888,
  4. num: 99999,
  5. };
  6. const poduc = JSON.stringify(produce);
  7. console.log(poduc);

Ajax

同步与异步

以前端请求,后端响应为例

  • 同步: 前端发请求, 必须等到后端响应完成,才允许发送另一个请求
  • 异步: 前端发请求后不等待后端响应结果继续执行,后端响应完成通过事件通知前端处理

    异步最常用的处理形式就是回调函数

XLMHttpRequest 对象

XMLHttpRequest是浏览器提供的,处理异步请求的宿主对象,而非 JS 内置对象
用于创建请求对象之中。
const obj = new XMLHttpRequest

GETPOST请求

  • GET请求
    GET请求的创建和完成方式分为以下几步:
    • 服务器: 返回 JSON
    • 前端: JSON.parse()解析 JSON 字符串

  1. 创建请求对象:new XMLHttpRequest
  2. 监听请求回调:onreadystatechange

    onreadystatechange:监听变量名.readystate变化 0,1,2,3,4表示成功。状态为 4 时表示请求回调成功

  3. 初始化请求参数:open

    语法:open(请求类型,请求地址,是否异步)
    演示:变量名.open("GET","http://youyou6.net/open.php",true)

  4. 发送请求:send()

    通常为send() 括号内的参数不写,但是为了避免其他浏览器识别出错,或出现其他 BUG,建议参数为null
    最终语法:send(null)

  5. 设置回调函数的方法来处理数据
  1. <title>Ajax-GET</title>
  2. <style>
  3. form {
  4. display: inline-grid;
  5. grid-template-columns: 5em 15em;
  6. gap: 1em;
  7. padding: 1em;
  8. border: 1px solid #000;
  9. background-color: lightcyan;
  10. }
  11. form button {
  12. grid-area: auto / 2 / auto / span 1;
  13. }
  14. </style>
  15. </head>
  16. <body>
  17. <form action="" onsubmit="return false;">
  18. <label for="username">用户名:</label>
  19. <input type="text" id="username" name="username" />
  20. <label for="email">邮箱:</label>
  21. <input type="email" id="email" name="email" />
  22. <button>保存</button>
  23. </form>
  24. <script>
  25. // 1.创建请求对象
  26. const url = new XMLHttpRequest();
  27. // 2.监听监控回调
  28. // 通过事件监听器监听变化,传值给show函数,采用冒泡方式
  29. url.addEventListener("readystatechange", show, false);
  30. // 3.初始化请求参数
  31. url.open("GET", "http://demo.io/test1.php", true);
  32. // 4.发送请求
  33. url.send(null);
  34. // 设置回调函数的处理方法
  35. function show(user) {
  36. if (url.readyState === 4) {
  37. // 返回的数据在url.responseText
  38. console.log(url.responseText);
  39. // json -> jsobj
  40. const user = JSON.parse(url.responseText);
  41. console.log(user);
  42. document.querySelector("#username").value = user.name;
  43. document.querySelector("#email").value = user.email;
  44. }
  45. }
  46. </script>

  • POST请求

    POST请求比GET请求就只多了一步:需要设置请求头: setRequestHeader()
    GET 请求,需要设置一个请求头,指明数据以哪种格式发送到服务器端
    其他四步和GET大同小异
    共有三种方式:通过表单form属性 enctype 可以查看到

      1. 创建请求对象: new XMLHttpRequest()
      1. 监听请求回调: onreadystatechange()
      1. 初始化请求参数: open(请求类型,请求地址,是否异步)
      1. 设置请求头: setRequestHeader()
      1. 发送请求: send(data)

        设置请求头的时候建议多增加一步,charset=utf-8
        最后请求头设置为:
        .setRequestHeader("content-type","编码格式;charset=utf-8")
        编码格式:content-type: 1.application/x-www-form-urlencoded 2.text-plain 3.application/jsonjson方式发送数据,但json方式只支持utf-8
  1. <script>
  2. // 1.创建请求对象
  3. const url = new XMLHttpRequest();
  4. // 2.监听请求回调
  5. url.addEventListener("readystatechange", show, false);
  6. // 3.初始化请求
  7. url.open("POST", "http://baidu.com", true);
  8. // 4.设置请求头
  9. // 以表单键值对的方式发送数据
  10. url.setRequestHeader("content-type", "application/x-www-form-urlencoded");
  11. // 5.发送请求
  12. url.send(null);
  13. // 回调函数处理办法:
  14. function show(ev) {
  15. if (url.readyState === 4) {
  16. // 值从responseText之中拿
  17. console.log(url.responseText);
  18. }
  19. }
  20. </script>


利用 JS 对象模拟表单数据

  1. // 用js对象来模拟表单数据
  2. const user = {
  3. email: "admin@php.cn",
  4. password: "123456",
  5. };
  6. // 前端是 js, 后端 php, php不能识别 js 对象,只能识别 json
  7. let data = JSON.stringify(user);
  8. // 4. 发送请求: `send()`
  9. url.send(data);

使用json来发送数据的话就要修改请求头格式,以json格式发送

  1. // 4. 设置请求头: `setRequestHeader()`
  2. // 以json格式发送数据, json只支持utf-8
  3. xhr.setRequestHeader("content-type", "application/json;charset=utf-8");

FormData

FormData:将数据封装后发送。
操作步骤:

  1. // 1.拿到表单和按钮
  2. const form = document.querySelector("form");
  3. const btn = document.querySelector("button");
  4. // 2.创建请求对象
  5. const url = new XMLHttpRequest();
  6. // 按钮点击事件
  7. btn.addEventListener("click", callback, false);
  8. // 将事件封包到一个表单之中
  9. function callback(ev) {
  10. // 3.监听请求回调
  11. url.addEventListener("readystatechange", show, false);
  12. // 4.初始化请求参数
  13. url.open("POST", "http://demo.io/data/test1.php", true);
  14. // 5.设置请求头
  15. url.setRequestHeader("content-type", "application/json");
  16. // 6.发送请求(使用FormData()来发送当前表单)
  17. url.send(new FormData(form));
  18. }
  19. // 请求的回调
  20. function show() {
  21. if (url.readyState === 4) {
  22. console.log(url.responseText);
  23. }
  24. }

跨域请求 JSONP

1. 跨域请求

  • 为了安全, 通过脚本发起的请求必须基于”同源策略”
  • 浏览器禁止使用 JS 脚本(Ajax)发起跨域请求(跨域资源共享)
  • 但是通过 html 标签跨域请求不能禁止的,毕竟这是互联网发明初衷

2. 同源策略

  • 协议, 域名, 端口完全相同, 则认为他们遵循了”同源策略”

    同源必须是协议httphttps,域名,端口都一直才叫同源,否则就不是同源

  1. # 协议不同
  2. https://www.caidu.cn:443 /course/812.html
  3. http:// www.caidu.cn:443 /course/812.html
  4. # 端口不同
  5. http://www.caidu.cn:80 /wenda/165068.html
  6. http://www.caidu.cn:8080 /wenda/165068.html
  7. # 域名不同
  8. http://www.caidu.net:80 /wenda/165068.html
  9. http://www.caidu.cn:80 /wenda/165068.html

3.跨域请求实现方法之一:JSNOP(最广泛)

4. JSONP:(JSON with Padding)

jsonp 仅限于GET方式
jsonp:重点在于 Url 的参数中必须要有一个回调参数
动态生成标签,标签必须要有src属性,如<img><script><ifarme>

为什么要使用跨域 JSONP?
Ajax 直接请求普通文件存在跨域无权限访问的问题,甭管你是静态页面、动态网页、web 服务、WCF,只要是跨域请求,一律不准,但是在 Web 页面上调用 JS 文件则不守是否跨域的影响。恰巧 json 就是一种通用的跨编程语言的轻量级数据交换/传输/存储格式,是一种纯字符类语言,我们可以随意调用和处理数据。

跨域请求的原理:

  1. 将数据封装到 JS 文件之中
  2. 在本地动态生成一个带有src属性的标签,调用服务端的 JS
  3. 本地通过该标签调用服务端的JS文件
  4. 服务端将数据通过回调函数将数据以Json格式传递给前端解析
  5. 调用成功

实例:

  • script标签允许跨域请求脚本: <script src="...."></script>
  • 动态生成<script>元素,并将需要跨域访问的 URL,赋值给 script 元素的 src 属性
  • 在跨域访问的服务器脚本中(如 php),将数据转为 json 格式,直接返回给前端处理就可以了
  • 原理就是这么简单,下面我们来实例演示
  • 创建一个站点:blog.io,并指向到当前项目的一个目录中,例如blog

回调函数和属性名(以名值对的方式向服务器发送给请求):

  1. <!DOCTYPE html>
  2. <html lang="">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>JSONP跨域请求</title>
  7. <style>
  8. form {
  9. display: inline-grid;
  10. grid-template-columns: 5em 15em;
  11. gap: 1em;
  12. padding: 1em;
  13. border: 1px solid #000;
  14. background-color: lightcyan;
  15. }
  16. form button {
  17. grid-area: auto / 2 / auto / span 1;
  18. }
  19. </style>
  20. </head>
  21. <body>
  22. <form action="" onsubmit="return false;">
  23. <label for="username">用户名:</label>
  24. <input type="text" id="username" name="username" />
  25. <label for="email">邮箱:</label>
  26. <input type="email" id="email" name="email" />
  27. <button>保存</button>
  28. </form>
  29. <hr />
  30. <button id="jsonp">JSONP跨域请求</button>
  31. <script>
  32. // 拿到按钮的bom属性
  33. const btn = document.querySelector("#jsonp");
  34. // 监听按钮的点击事件
  35. btn.addEventListener("click", creatScript, false);
  36. // createScirpt()动态创建<script>
  37. function creatScript() {
  38. // 这里的url内的show就相当于callback函数
  39. // 以get方法添加查询参数,就是放在url中,以键值对方式添加每个键值对之间用&分割
  40. let url = "http://blog.io/index.php?id=3&jsonp=show";
  41. // 生成script元素
  42. const script = document.createElement("script");
  43. // 将跨域请求的url赋值给src属性
  44. script.src = url;
  45. // 将script添加到页面之中
  46. document.head.appendChild(script);
  47. }
  48. // 回调函数show,为什么是show,请看url,我们定义了一个callback返回函数接收数据
  49. function show(user) {
  50. // 服务端返回的数据以及自动解析为了JS对象,所以可以直接引用
  51. console.log(user);
  52. document.querySelector("#username").value = user.name;
  53. document.querySelector("#email").value = user.email;
  54. }
  55. </script>
  56. </body>
  57. </html>

服务端代码:

  1. <?php
  2. $users = [
  3. ['id'=>1, 'name'=>'admin', 'email'=>'admin@php.cn'],
  4. ['id'=>2, 'name'=>'peter', 'email'=>'peter@php.cn'],
  5. ['id'=>3, 'name'=>'jack', 'email'=>'jack@php.cn'],
  6. ];
  7. // 查询条件
  8. // 通过前端发送请求的url内的id来查询
  9. $id = $_GET['id'];
  10. // js回调
  11. $callback = $_GET['jsonp'];//回调变量名:可在前端跨域请求url之中查看到
  12. foreach ($users as $user) {
  13. if ($user['id'] == $id) {
  14. $result = $user;
  15. break;
  16. }
  17. }
  18. $data = json_encode($result);
  19. // 创建一条js函数的调用语句返回
  20. // echo "函数名(参数)";
  21. echo "{$callback}({$data})";

最终跨域拿到数据:

Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:其实ajax的四步/五步操作还是有点繁琐了, 有空了解一下fetch api,这才是以后的主流, 是不是有点学不动的感觉了, 没办法呀,选择了这行
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post