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
目录
相关文章
|
1月前
|
数据采集 前端开发 JavaScript
虎扑APP数据采集:JavaScript与AJAX的结合使用
虎扑APP数据采集:JavaScript与AJAX的结合使用
|
3月前
|
移动开发 前端开发 JavaScript
js之ajax |12-6
js之ajax |12-6
|
4月前
|
JavaScript 前端开发 网络协议
|
4月前
|
前端开发 JavaScript API
JavaScript异步编程2——结合XMLHttpRequest使用Promise
JavaScript异步编程2——结合XMLHttpRequest使用Promise
27 0
|
4月前
|
JavaScript 前端开发 安全
js之AJAX
js之AJAX
35 0
|
5月前
|
XML 前端开发 JavaScript
JavaScript进阶 - AJAX请求与Fetch API
【7月更文挑战第9天】JavaScript进阶:AJAX与Fetch API对比。AJAX用于异步数据交换,XMLHttpRequest API复杂,依赖回调。Fetch API是现代、基于Promise的解决方案,简化请求处理。示例:`fetch(&#39;url&#39;).then(r =&gt; r.json()).then(data =&gt; console.log(data)).catch(err =&gt; console.error(err))`。注意点包括检查HTTP状态、错误处理、CORS、Cookie和超时。Fetch提高了异步代码的可读性,但需留意潜在问题。
105 0
|
前端开发 JavaScript 网络协议
【node.js从入门到精通】编写接口,使用CROS解决跨域问题,jsonp的接口
【node.js从入门到精通】编写接口,使用CROS解决跨域问题,jsonp的接口
218 0
【node.js从入门到精通】编写接口,使用CROS解决跨域问题,jsonp的接口
|
JavaScript 前端开发 测试技术