博客列表 >javascript 中 ajax 请求和 jsonp 跨域的问题

javascript 中 ajax 请求和 jsonp 跨域的问题

存在
存在原创
2020年11月07日 02:36:22614浏览

一,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 一段时间,感觉有点难度!主要是属性和对象太多了,还是要多敲代码,才能熟能生巧!

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议
存在2020-11-07 15:47:081楼
谢谢老师夸奖!