Blogger Information
Blog 9
fans 0
comment 6
visits 9536
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
javascript 中 ajax 请求和 jsonp 跨域的问题
存在
Original
617 people have browsed it

一,ajax

1.ajax

什么是 ajax?
Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式、快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。

ajax 能极大地提升用户体验,在开发中经常使用!

同步和异步
在了解 ajax 之前首先要明白两个概念:

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

比如李二狗在房间烧水。
同步:在水烧开之前李二狗啥也不做就目不转睛的盯着水壶等它烧开。
异步:水烧开前李二狗顺便把地拖了一遍,还把碗也洗干净了。等水烧开发出‘呜呜’的声音,二狗便知道已经烧开了,可以过来把它提走。

XMLHttpRequest
XMLHttpRequest 是一个浏览器接口,使得 Javascript 可以进行 HTTP(S)通信。

最早,微软在 IE 5 引进了这个接口。因为它太有用,其他浏览器也模仿部署了,ajax 操作因此得以诞生。

XMLHttpRequest 对象的主要属性:

  • xhr.readyState:XMLHttpRequest 对象的状态,等于 4 表示数据已经接收完毕。
  • xhr.status:服务器返回的状态码,等于 200 表示一切正常。
  • xhr.responseText:服务器返回的文本数据
  • xhr.responseXML:服务器返回的 XML 格式的数据
  • xhr.statusText:服务器返回的状态文本。

这个对象是浏览器提供的,是处理异步请求的宿主对象,而非 JS 内置对象
想了解这个对象的详情请点击:http://www.ruanyifeng.com/blog/2012/09/xmlhttprequest_level_2.html

2.ajax 请求方式

ajax 的 http 请求方式有两种:POST 和 GET。

2.1 GET 方式

请求流程:
a. 创建请求对象: new XMLHttpRequest()
b. 监听请求回调: onreadystatechange
c. 初始化请求参数: open(请求类型,请求地址,是否异步)
d. 发送请求: send()

响应:
a. 服务器: 返回 JSON
b. 前端: JSON.parse()解析 JSON 字符串

  • JS 代码
  1. // dom 获取按钮
  2. let btn = document.querySelector("button");
  3. // console.log(btn);
  4. // 点击按钮发送请求
  5. btn.addEventListener("click", request, false);
  6. //建立ajax句柄
  7. const getHandle = new XMLHttpRequest();
  8. // 监听readystate 状态,用onreadystatechange方法监听
  9. getHandle.addEventListener("readystatechange", show, false);
  10. //设定请求方式;get|post
  11. getHandle.open("GET", "test1.php", true);
  12. // 点击按钮请求回调
  13. function request(ev) {
  14. //发送ajax请求
  15. // getHandle.send();
  16. // 为了兼容一些老版的浏览器最好在方法里面加上个null
  17. getHandle.send(null);
  18. }
  19. // ajax请求状态监听
  20. function show() {
  21. if (getHandle.readyState === 4) {
  22. console.log(getHandle.responseText);
  23. }
  24. }
  • PHP 代码
  1. // aja get请求脚本
  2. echo '成功返回数据';
  • 效果

ajax;

2.2 POST 方式

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

响应:
a. 服务器: 返回 JSON
b. 前端: JSON.parse()解析 JSON 字符串

注意:post 与 get 相比, 多了一步设置请求头。

  • 表单数据格式
    前端发送 JSON,后端如果 json 数据以表单数据类型发送,可用$_POST 接收,数据是常见表单名值对格式。

    • JS 代码
    1. // 运用ajax post 表单名值对格式(application/x-www-form-urlencoded)方式请求数据
    2. // 建立句柄
    3. const handle = new XMLHttpRequest();
    4. // console.log(handle);
    5. // 监听状态 0,1,2,3,4
    6. handle.addEventListener("readystatechange", show, false);
    7. //设定请求方式
    8. handle.open("POST", "test2.php", true);
    9. //设置请求头
    10. handle.setRequestHeader("content-type", "application/x-www-form-urlencoded");
    11. // 请求数据(伪数据)
    12. const user = {
    13. name: "zhangshan",
    14. age: 30,
    15. };
    16. //因为php无法识别js的数据格式,因此此处要把数据转为跨语言的json字符串格式
    17. let data = JSON.stringify(user);
    18. // console.log(data);
    19. // 发送ajax post请求
    20. handle.send(data);
    21. function show(e) {
    22. if (handle.readyState == 4) {
    23. console.log(handle.responseText);
    24. }
    25. // console.log(readstate);
    26. }
    • PHP 代码
    1. // ajax post请求脚本
    2. $data = key($_POST);
    3. echo $data;
    • 效果

    ajax;

  • json 数据格式
    如果 json 数组就是以 JSON 发送, php://input 流文件方式接收

    • JS 代码
    1. // 向服务器传输json格式数据
    2. // 建立句柄
    3. const handle = new XMLHttpRequest();
    4. // 监听事件 onreadystatechange 监听readystate属性状态 状态
    5. handle.addEventListener("readystatechange", change, false);
    6. //设置ajax 请求方式 post get
    7. handle.open("POST", "test3.php", true);
    8. //设置请求头
    9. handle.setRequestHeader("content-type", "application/json;charset=utf-8");
    10. //伪数据
    11. const data = {
    12. name: "zhangshan",
    13. age: 30,
    14. };
    15. // 转为json 字符串
    16. let jsonData = JSON.stringify(data);
    17. // console.log(jsonData);
    18. //请求
    19. handle.send(jsonData);
    20. function change(obj) {
    21. if (handle.readyState === 4) {
    22. console.log(handle.responseText);
    23. }
    24. }
    • PHP 代码
    1. //ajax 传递json格式字符串脚本
    2. //接收前端传来的json格式的数据.因为数据格式不是表单数据,所以不能用$_POST接收
    3. // $user = $_POST;
    4. //用php://input;
    5. $user = file_get_contents('php://input');
    6. echo $user;
    • 效果

    ajax;

  • FormData 封装表单数据数据
    FormData 数据不需要设置请求头,因为在 FormData 对象中已经封装了请求头信息

    • HTML 代码
    1. <form action="" onsubmit="return false">
    2. <input type="text" name="username" value="李四" placeholder="用户名" />
    3. <input type="password" name="psd" value="123456" placeholder="用户名" />
    4. <button type="button">提交</button>
    5. </form>
    • JS 代码
    1. // 点击发送ajax
    2. let form = document.querySelector("form");
    3. // 获取button,表单数据
    4. let btn = document.querySelector("button");
    5. //button添加点击事件
    6. btn.addEventListener("click", sumbumit, false);
    7. // ajax请求
    8. const handle = new XMLHttpRequest();
    9. // 监听readystate 状态,用onreadystatechange方法监听
    10. handle.addEventListener("readystatechange", show, false);
    11. //设置ajax 请求方式 post get
    12. handle.open("POST", "test4.php", true);
    13. //提交回调:FormData封装表单数据提交
    14. function sumbumit(ev) {
    15. // 发送数据
    16. handle.send(new FormData(form));
    17. }
    18. // ajax请求状态监听
    19. function show() {
    20. if (handle.readyState === 4) {
    21. console.log(handle.responseText);
    22. }
    23. }
    • PHP 代码
    1. // ajax FormData 返回
    2. print_r($_POST);
    • 效果

    ajax;

二,jsonp 跨域的问题

浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源.

1,原因

同源策略

1995 年,同源政策由 Netscape 公司引入浏览器。目前,所有浏览器都实行这个政策。

最初,它的含义是指,A 网页设置的 Cookie,B 网页不能打开,除非这两个网页”同源”。

所谓”同源”指的是”三个相同”。

  • 协议相同
  • 域名相同
  • 端口相同

举例:

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

2,跨域原理

  • script标签允许跨域请求脚本: <script src="...."></script>
  • 动态生成<script>元素,并将需要跨域访问的 URL,赋值给 script 元素的 src 属性
  • 在跨域访问的服务器脚本中(如 php),将数据转为 json 格式,直接返回给前端处理就可以了

注意:在访问的 URL 中一定要带上 callback 回调函数,回调函数是在当前请求的 js 脚本中申明,并在 php 中调用返回数据。

3,实现

  • HTML 代码
    <button class="btn">跨域请求</button>
  • JS 代码
  1. // 由于浏览器同源策略,我们没法拿到其他网站的数据,为了规避它,我们运用jsonp跨域
  2. // 在脚本中生成 script 标签
  3. let btn = document.querySelector("button.btn");
  4. btn.addEventListener("click", creatScript, false);
  5. function creatScript(ev) {
  6. // script请求地址
  7. let url = "http://www.test.com/test1.php?id=1&callback=show";
  8. // 生成script标签对象
  9. let script = document.createElement("script");
  10. script.src = url;
  11. document.head.appendChild(script);
  12. }
  13. function show(data) {
  14. console.log(data);
  15. }
  • PHP 代码
  1. $data = [
  2. ['id'=>1,'name'=>'zhangshan','age' => 20],
  3. ['id'=>2,'name'=>'lisi','age' => 30],
  4. ['id'=>1,'name'=>'wanmazi','age' => 40],
  5. ];
  6. $id = $_GET['id'];
  7. //echo $id;die;
  8. $callback = $_GET['callback'];
  9. $ret;
  10. foreach($data as $value) {
  11. if($value['id'] == $id) {
  12. $ret = $value;
  13. break;
  14. }
  15. }
  16. $ret = json_encode($ret);
  17. echo "{$callback}({$ret})";
  • 效果

ajax;

三,总结

学习了 js 一段时间,感觉有点难度!主要是属性和对象太多了,还是要多敲代码,才能熟能生巧!

Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:做为才学了一周的js, 能写出这么代码已不容易了, 想当年, 这可是我几个月才能达到的境界,你一周就可以做到了, 恭喜你
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
1 comments
存在 2020-11-07 15:47:08
谢谢老师夸奖!
1 floor
Author's latest blog post