美文网首页
从 AJAX 到跨域问题

从 AJAX 到跨域问题

作者: 梧桐月明中 | 来源:发表于2020-08-28 18:15 被阅读0次

本文目前为止只是个概述笔记,原文是个系列文章,链接在最后的参考部分,写得非常好,强烈推荐。

AJAX 是什么

Asynchronous JavaScript And XML

xml 和 json

  • 最初互联网数据都是通过 xml(可扩展标记语言)传输的
  • 后来 json 巨多,json 只是数据
  • xml 是语言,依旧有自己的优势场景

目的 -> 无页面刷新获取服务端数据

是一种混合技术 -> JS、客户端、服务端

  • JS,用于获取数据后以操作 DOM 或其它方式达成目标
  • 客户端(即浏览器),提供 XMLHttpRequest 对象
  • 服务端,拥有允许客户端向其发起 AJAX 请求的相关设置

使用 AJAX

怎样通过 JS 发送 AJAX 请求?

核心:XMLHttpRequest 对象 (构造函数)

方法

  • .open() 准备启动一个 AJAX 请求
  • .setRequestHeader() 设置请求头部信息
  • .send() 发送 AJAX 请求
  • .getResponseHeader() 获取响应头部信息
  • .getAllResponseHeader() 获取一个包含所有响应头部信息的长字符串
  • .abort() 取消异步请求

属性

  • .responseText 响应返回的主体文本
  • .responseXML 响应内容类型为 text/xmlapplication/xml 时,该属性包含响应返回的 XML DOM 文档
  • .status 响应的 HTTP 状态
  • .statusText HTTP 状态的说明
  • .readyState 表示“请求/响应”过程的当前活动阶段

监听事件

  • .onreadystatechange() 监听 readyState 的变化

使用流程?

准备 open()

  • get/post
  • url ,查询参数
    注意:参数的名和值都需要 encodeURIComponent 进行编码
    注意:若 url 为相对地址,应该是相对于执行此代码的页面
  • 同步/异步

设置请求头

  • 默认的请求头
  • setRequestHeader()
    注意部分浏览器不允许重写默认的请求头,因此自定义请求头是比较安全的做法

发送数据

  • get -> send(null) 注意:send 必须有参数,所以需要传个 null
  • post -> send(data)

处理响应

  • 异步 onreadystatechange readystate 0/1/2/3/4
  • 注意,事件处理函数写在 .open() 前(以保证浏览器兼容性)

取消异步请求

  • xhr.abort()
  • 注意,取消后要手动给 xhr 解绑(xhr = null)以释放内存

XMLHttpRequest 二级

在之前的基础上,W3C 提出了 XMLHttpRequest 二级规范,但是并不是所有浏览器都实现了,介绍一些被全部或多数浏览器实现的功能。

FormData 类型

超时设定

  • timeout
  • ontimeout
  • 注意,超时后请求中止,会调用 ontimeout,但此时有可能 readyState 已经变为4,这意味着会继续调用 onreadystatechange,但是当超时请求中止后再访问 status 属性浏览器会报错误,因此需要将检查 status 的语句放入 try catch 中

overrideMimeType() 方法

进度事件

  • onloadstart
  • onprogress
  • onerror
  • onabort
  • onload
  • onloadend

跨域问题

缘起?同源策略

AJAX 使数据传输变得方便,但是对于某些数据,隐私和安全需要重视,因此有了同源策略,来进行能力限制。

浏览器的同源策略:限制不同之间执行特定操作

  • 一个源由协议、域名和端口三部分组成,三者中任一一个不同,都会被浏览器认为是不同的源。
  • 特定的操作是指:
    • 读取 Cookie、LocalStorage 和 IndexDB
    • 获取 DOM 元素
    • 发送 AJAX 请求

为什么要限制这些特定操作

  • 很多网站会把用户名密码之类的数据存放到 Cookie,如果没有同源策略,我们就可以通过 JS 脚本读取到浏览器里存储的所有网站的 Cookie,有了同源策略,我们只能读取到自己的网站域名下的 Cookie,相当于只能读取自己设置的。
  • 如果能够获取其它源下的 DOM,那么利用 iframe 标签引入其它网站内容,诱导用户操作表单,由于能够获取其它站点的 DOM,就可以监听和操作 DOM,例如可以获取用户输入的密码。
  • 为什么要禁止发送 AJAX 请求呢?这和 Cookie 的运作原理有关。每一条 Cookie 都由 domain 和 path 两个属性来标识它所属的源,当浏览器发送 Http 请求时,它会自动查找与请求 URL 匹配的 Cookie,如果有,就会自动加入到 header 头的 Cookie 属性中发送出去,服务器返回信息,会原封不动地把这个 Cookie 内容加到返回头里传回来。嗅到危险了吗?如果没有同源策略,我们在自己的服务器上托管网站 A,在 A 网站被访问时,运行我们的脚本,脚本向 B 网站(比如是个银行网站)发送一个请求,如果这个用户的浏览器恰好保存有 B 网站的 Cookie,那么我们就可以通过请求的返回头拿到这个 Cookie 了。

同源策略的表现

  • JS 读取 Cookie 等只能读到自己所在域的数据。
  • iframe 标签里只显示一个空空的 #document 节点。
  • 对于跨域的 AJAX 请求,在响应返回时,浏览器识别出来给拦下,只报个错误出来告诉跨域了。

跨域解决方案

(一)JSONP - 野路子出身却异常好用

  • JSON with padding,包裹的 json
  • 原理就是不用 AJAX 了,用 script 标签来达到目的。script 标签不受跨域限制,加载进来的脚本就会立即执行。怎么实现呢?来看客户端的用法:
function handleResponse(response){
  alert(`You got the response data: ${response}`)
}
const script = document.createElement('script')
script.src = 'http://somesite.com/json/?callback=handleResponse'
document.body.insertBefore(script, document.body.firstChild)
  • 是不是迷惑了?response 到底是怎样拿到的?别急,关键的部分就在服务器了:服务器识别 url 解析出 callback 的函数名 handleResponse,然后把需要返回的 json 数据作为参数传入 handleResponse,把执行这个函数语句作为响应返回给浏览器。
  • 浏览器加载到这个脚本后直接执行,就弹出了 response 的内容了。
  • 是不是很巧妙呢,JSONP,这个 padding 原来就是我们的 callback 函数。

(二)CORS - 官方推荐的跨域资源共享方案

(坑,待填)

(三)使用 HTML5 API:postMessage

(坑,待填)

(四)抛弃 HTTP,使用:Web Sockets

(坑,待填)


参考

再也不学AJAX了!(一)AJAX概述
再也不学AJAX了!(二)使用AJAX
再也不学AJAX了!(三)跨域获取资源 ① - 同源策略
再也不学AJAX了!(三)跨域获取资源 ② - JSONP & CORS
再也不学AJAX了!(三)跨域获取资源 ③ - WebSocket & postMessage

相关文章

  • 解决ajax跨域问题

    Jsonp解决ajax跨域问题 CORS解决ajax跨域问题

  • 从 AJAX 到跨域问题

    本文目前为止只是个概述笔记,原文是个系列文章,链接在最后的参考部分,写得非常好,强烈推荐。 AJAX 是什么 As...

  • Http浅析【2】——ajax跨域问题

    视频参考:ajax跨域完全讲解 本文精华版:【综合】ajax跨域问题 什么是跨域问题 简单来讲,当前台调用后台,如...

  • 前端跨域

    什么是ajax跨域 ajax跨域的原理 ajax出现请求跨域错误问题,主要原因就是因为浏览器的“同源策略”,可以参...

  • ajax跨域请求

    ajax跨域请求(jsonp) 利用JSONP解决AJAX跨域问题的原理与jQuery解决方案JSONP jQue...

  • window.postMessage解决前端ajax跨域问题

    postMessage畅快解决跨域问题 本文主要是记录使用window.postMessage解决ajax跨域问题...

  • 使用JSONP解决ajax跨域

    在日常开发中,不免遇到跨域的问题。在这里我们介绍使用Jsonp来解决ajax跨域的问题 什么是跨域? 跨域,指的是...

  • Flask-cors跨域

    什么是跨域 为什么要考虑跨域问题 同源策略 解决跨域问题 方式一: 使用 JSONP (一种非Ajax技术,需要前...

  • SpringMVC 进行ajax跨域请求访问

    关于 springmvc 3.x 版本对ajax跨域请求访问 ajax 请求后,浏览器出现跨域的问题那么在当前环境...

  • 解决跨域问题

    概述 在浏览器端进行 Ajax 请求时会出现跨域问题,那么什么是跨域,如何解决跨域呢?先看浏览器端出现跨域问题的现...

网友评论

      本文标题:从 AJAX 到跨域问题

      本文链接:https://www.haomeiwen.com/subject/mlmajktx.html