js【详解】ajax (含XMLHttpRequest、 同源策略、跨域、JSONP)

简介: js【详解】ajax (含XMLHttpRequest、 同源策略、跨域、JSONP)

ajax 的核心API – XMLHttpRequest

get 请求

// 新建 XMLHttpRequest 对象的实例
const xhr = new XMLHttpRequest();
// 发起 get 请求,open 的三个参数为:请求类型,请求地址,是否异步请求( true 为异步,false 为同步)
xhr.open("GET", "/data/test.json", false);

// 定义 xhr 状态改变的处理函数
xhr.onreadystatechange = function () {
  // xhr 的 readyState 属性变为 4
  if (xhr.readyState === 4) {
    // 网络请求返回的状态码为 200
    if (xhr.status === 200) {
      alert(xhr.responseText);
    } else if (xhr.status === 404) {
      // 网络请求返回的状态码为 404
      console.log("404 not found");
    } else {
      console.log("其他情况");
    }
  }
};

// 发出请求,会触发 xhr 状态的改变
xhr.send(null);

post 请求

// 新建 XMLHttpRequest 对象的实例
const xhr = new XMLHttpRequest();
// open 的三个参数为:请求类型,请求地址,是否异步请求( true 为异步,false 为同步)
xhr.open("POST", "/login", false);

// 定义 xhr 状态改变的处理函数
xhr.onreadystatechange = function () {
  // xhr 的 readyState 属性变为 4
  if (xhr.readyState === 4) {
    // 网络请求返回的状态码为 200
    if (xhr.status === 200) {
      alert(xhr.responseText);
    } else if (xhr.status === 404) {
      // 网络请求返回的状态码为 404
      console.log("404 not found");
    } else {
      console.log("其他情况");
    }
  }
};

// 定义 post 请求的参数
const postData = {
  userName: "朝阳",
  password: "xxx",
};

// 发出请求 -- 参数需转为字符串
xhr.send(JSON.stringify(postData));

XMLHttpRequest 的 readyState 属性

  • 0 —— UNSET 尚未调用 open方法
  • 1 —— OPENED open 方法已被调用
  • 2 —— HEADERS RECEIVED send 方法已被调用,header 已被接收
  • 3 —— LOADING 下载中,responseText已有部分内容
  • 4 —— DONE 下载完成

XMLHttpRequest 的 status 属性

即 http 请求的状态码,详见

https://blog.csdn.net/weixin_41192489/article/details/136446539

同源策略

ajax 请求地址的 协议、域名、端口 必须和当前网页的地址相同!

  • 浏览器中的 ajax 请求才有同源策略限制
  • 图片、css文件、js文件的加载,没有同源策略限制,应用如下:
  • 图片用于使用第三方统计服务完成统计打点(如统计网页浏览量)
  • 使用 CDN 加速图片、css文件、js文件
  • <script> 可用于实现 JSONP

跨域

所有的跨域,都必须经过 server 端允许和配合

【考题】哪些 html标签能绕过跨域 ?

  • <a>标签的href属性可以实现跨域链接,但是只能用于GET请求
<a href="http://baidu.com">跨域链接</a>
  • <img>标签的src属性可以加载跨域图片
<img src="http://**.jpg" alt="跨域图片">
  • <link>标签的href属性可以加载跨域样式表。
<link rel="stylesheet" href="http://**.cn/styles.css">
  • <script>标签的src属性可以加载跨域脚本文件,常用于JSONP跨域请求。
<script src="http://**.cn/api.js"></script>

以上标签和属性只是在特定情况下可以用于跨域请求,具体是否允许跨域请求还要看服务器端是否设置了相应的CORS(跨域资源共享)策略。如果服务器没有设置CORS策略,浏览器会阻止跨域请求。

方案一 JSONP

JSONP 实现跨域的过程:借助 script 标签没有同源策略限制的特点,向跨域的目标服务器加载到需要的数据。

范例:

 <script>
     window.callback= function (data) {
         console.log(data)
     }
 </script>
 <script src="http://localhost:8008/jsonp.js"></script>

jsonp.js

callback(
    { name: '朝阳' }
)

借助 script 标签 向目标服务器加载到 jsonp.js 文件,执行 callback 函数,因本地已定义了 callback 函数,便会触发本地 js 代码的执行,获取到 jsonp.js 文件中的数据,从而实现了跨域。

jQuery 实现 jsonp

jQuery 内实现 jsonp 的方式与范例中相同,只是进行了封装。

方案二 跨域资源共享 CORS

服务器设置 http header,即服务器端将指定网址设置为白名单,允许它以指定的方法进行跨域访问。(纯服务端的修改实现,和前端无关)

更多详情参考

最常见的六种跨域解决方案_跨域问题解决方案

【考题】手写一个简易的 ajax

function ajax(url) {
    const p = new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest()
        xhr.open('GET', url, true)
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    resolve(
                        JSON.parse(xhr.responseText)
                    )
                } else if (xhr.status === 404 || xhr.status === 500) {
                    reject(new Error('404 not found'))
                }
            }
        }
        xhr.send(null)
    })
    return p
}
const url = '/data/test.json'
ajax(url)
.then(res => console.log(res))
.catch(err => console.error(err))

【考题】怎么实现跨域?

  • JSONP
  • CORS

实战中实现 ajax 的常用插件

  • jQuery
  • fetch —— 新增的 Web API
  • axios
目录
相关文章
|
5天前
|
XML 前端开发 JavaScript
JavaScript进阶 - AJAX请求与Fetch API
【7月更文挑战第3天】前端开发中的异步基石:AJAX与Fetch。AJAX,使用XMLHttpRequest,处理跨域、回调地狱和错误处理。Fetch,基于Promise,简化请求,但需注意默认无跨域头和HTTP错误处理。两者各有优劣,理解其问题与解决策略,能提升前端应用的性能和用户体验。
|
18天前
|
JavaScript 前端开发 安全
安全开发-JS应用&原生开发&JQuery库&Ajax技术&加密编码库&断点调试&逆向分析&元素属性操作
安全开发-JS应用&原生开发&JQuery库&Ajax技术&加密编码库&断点调试&逆向分析&元素属性操作
|
8天前
|
前端开发 JavaScript 安全
详尽分享突破ajax不能跨域的限制
详尽分享突破ajax不能跨域的限制
|
17天前
|
XML 移动开发 前端开发
JS设置Ajax为同步或异步
JS设置Ajax为同步或异步
11 0
|
17天前
|
XML JSON 前端开发
第十一篇JavaScript JSON与AJAX
第十一篇JavaScript JSON与AJAX
12 0
|
2月前
|
XML 前端开发 JavaScript
【JavaScript技术专栏】JavaScript网络请求与Ajax技术
【4月更文挑战第30天】Ajax是Web开发中实现动态数据更新的关键技术,允许不刷新页面即从服务器获取数据。它结合了HTML/CSS、DOM、XML/JSON和JavaScript。`XMLHttpRequest`是传统的Ajax实现方式,而`fetch` API是现代、简洁的替代选项。Ajax应用实例展示了如何使用fetch在搜索框输入时异步获取并显示结果,提升了用户体验。掌握这些技术对前端开发者至关重要。
|
Web App开发 JavaScript 安全
JavaScript跨域总结与解决办法
JavaScript跨域总结与解决办法 http://kb.cnblogs.com/page/91822/ 作者: kang !  来源: 博客园  发布时间: 2011-02-22 22:49  阅读: 1011 次  原文链接   全屏阅读  [收藏]   编辑点评:JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象。
|
2天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的个人健康管理系统小程序附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的个人健康管理系统小程序附带文章源码部署视频讲解等
11 2