ajax url 跨越,跨越跨域大山,前端不得不知道的Ajax

  • Post author:
  • Post category:其他


引言

ajax对于前端来说是一个特别基础也特别实用的一个功能,基本上我们目前访问的很多网页都有用到 ajax 的功能。接下来开始讲解关于AJAX请求,以及关于跨域的一些内容。

正文

一、AJAX请求

Ajax ,即 Asynchronous Javascript And XML(异步JavaScript和XML)。

在实现 Ajax 之前,我们先来了解下 XMLHttpRequest 。 XMLHttpRequest 是网页实现 AJAX 最主要的一个 API 。可能有很多同学知道 AJAX ,也用过 AJAX ,但是却不知道它是基于 XMLHttpRequest 来实现的。

那么接下来我们用 XMLHttpRequest 这个 API 来模拟一个 get 和 post 请求。

1、模拟get和post请求

(1)模拟get请求:

/**

* 使用xhr模拟实现GET请求

*/

const xhr = new XMLHttpRequest();

xhr.open(‘GET’, ‘/test.json’, true); //false表示同步请求,true表示异步请求

xhr.onreadystatechange = function () {

// 这里的函数异步执行

if(xhr.readyState === 4){

if(xhr.status === 200){

// console.log(

// JSON.parse(xhr.responseText)

// );

alert(xhr.responseText);

}

}

}

// 因为是get请求,所以只要发送null就好

xhr.send(null);

(2)模拟post请求:

/**

* 使用xhr模拟实现post请求

*/

const xhr = new XMLHttpRequest();

//模拟请求一个登录接口

xhr.open(‘POST’, ‘/login’, true); //false表示同步请求,true表示异步请求

xhr.onreadystatechange = function(){

if(xhr.readyState === 4){

if(xhr.status === 200){

console.log(

JSON.parse(xhr.responseText)

);

alert(xhr.responseText);

}else{

console.log(‘其他情况’);

}

}

}

const postData = {

userName: ‘zhangsan’,

password: ‘xxx’

}

xhr.send(JSON.stringify(postData));

2、封装一个简易的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){

reject(new Error(‘404 not found’));

}

}

}

xhr.send(null);

});

return p;

}

const url = ‘你的json数据路径’;

ajax(url)

.then(res => console.log(res))

.catch(err => console.error(err));

二、状态码

看完上面的模拟过程之后,我们来讲解其中的几个知识点。

1、xhr.readyState

readyState状态值readyState含义0(未初始化)- 还没有调用send()方法

1(载入)- 已调用send()方法,正坐在发送请求

2(载入完成)- send()方法执行完成,已经接收到全部响应内容

3(交互)- 正在解析响应内容

4(完成)响应内容解析完成,可以在客户端调用

2、xhr.status

status状态值status含义2xx表示成功处理请求,如200

3xx需要重定向,浏览器直接跳转,如301 302 304

4xx客户端请求错误,如404 403

5xx服务器端错误

三、跨域

1、同源策略

(1)同源策略是什么

同源策略是浏览器自带的一种安全策略,它是指网址中的协议、域名、端口三个都相同时才能互相访问,即若协议、域名、端口有一个不相同时,浏览器禁止页面加载或执行与自身不同域的脚本。

(2)为什么浏览器会有同源策略?

因为如果没有同源策略,别人就可以轻松的获取我们网站的 cookie 信息,或是对网页进行 DOM 操作;

这是一件非常恐怖的事情,尤其是 cookie 信息,它里面存在着 sessionID ,这是与服务端的 session 会话的重要凭证,如果被别人得到了 cookie ,有很大可能会造成数据被盗取等后果。

(3)同源策略限制内容有哪些?

存储在浏览器中的数据,如 localStroage 、 Cookie 和 IndexedDB 不能通过脚本跨域访问;

不能通过脚本操作不同域下的 DOM ;

不能通过 ajax 请求不同域的数据。

(4)加载图片、js和css时可以无视同源策略

%E8%B7%A8%E5%9F%9F%E7%9A%84%E5%9B%BE%E7%89%87%E5%9C%B0%E5%9D%80

如以上代码所示,当我们在加载以上类型的 图片、css和js 时,可以无视同源策略。因为像 图片、css文件和js文件 一般可使用 cdn 来进行缓存,而 cdn 一般是外域。同时, js 文件也可以通过 JSONP 来实现跨域。

2、跨域解决方案

(1)跨域是什么

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

未经 server 端允许就实现跨域,说明浏览器有漏洞,是一种危险信号。

(2)解决跨域的方式

1)JSONP(客户端操作)

① JSONP的原理

JSONP(JSON with Padding)是数据格式 JSON 的一种“使用模式”,可以让网页从别的网域要数据。

根据 XmlHttpRequest 对象受到同源策略的影响,而利用

用 JSONP 抓到的数据并不是 JSON ,而是任意的 JavaScript ,用 JavaScript 解释器运行而不是用 JSON 解析器解析。

所以,通过 Chrome 查看所有 JSONP 发送的 Get 请求都是 js 类型,而非 XHR 。

② JSONP包含两部分:回调函数和数据

回调函数是当响应到来时要放在当前页面被调用的函数。

数据就是传入回调函数中的 json 数据,也就是回调函数的参数了。

function handleResponse(response){

console.log(‘The responsed data is: ‘+response.data);

}

var script = document.createElement(‘script’);

script.src = ‘http://www.baidu.com/json/?callback=handleResponse’;

document.body.insertBefore(script, document.body.firstChild);

/*handleResonse({“data”: “zhe”})*/

//原理如下:

//当我们通过script标签请求时

//后台就会根据相应的参数(json,handleResponse)

//来生成相应的json数据(handleResponse({“data”: “zhe”}))

//最后这个返回的json数据(代码)就会被放在当前js文件中被执行

//至此跨域通信完成

③ 缺点:

只能使用Get请求。

不能注册success、error等事件监听函数,不能很容易的确定 JSONP 请求是否失败。

JSONP 是从其他域中加载代码执行,容易受到跨站请求伪造的攻击,其安全性无法确保。

2)CORS(服务器操作)

① cors的原理

CORS (Cross-Origin Resource Sharing),即跨域资源共享,是一种浏览器技术的规范,提供了 Web 服务从不同域传来沙盒脚本的方法,以避开浏览器的同源策略,确保安全的跨域数据传输。现代浏览器使用 CORS 在 API 容器如 XMLHttpRequest 来减少 HTTP 请求的风险来源。与 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。

② cors 的跨域方法一般是服务端进行操作,服务端需要设置以下 http header :

//设置允许跨域的域名称,不建议直接写“*”

response.setHeader(“Access-Control-Allow-Origin”, “http://localhost:8080”);

//填写允许跨域的http请求方法

//当 method = OPTIONS 时, 属于预检(复杂请求), 当为预检时, 可以直接返回空响应体, 对应的 http 状态码为 204

response.setHeader(“Access-Control-Allow-Methods”, “PUT,POST,GET,DELETE,OPTIONS”);

//设置需要支持的跨域请求头,如果设置为*,表明服务器支持所有头信息字段;也可设置为X-Request-With和Content-Type

response.setHeader(“Access-Control-Allow-Headers”, “X-Request-With, Content-Type”);

// 服务器收到请求以后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。

//表示具体请求中的媒体类型信息

response.setHeader(“Content-Type”, “application/json;charset=utf-8”);

//设置预检结果的缓存, 单位(秒)

response.setHeader(“Access-Control-Max-Age”, 86400);

/*如果需要支持 cookies,

*Access-Control-Allow-Origin 不能设置为 *,

*并且 Access-Control-Allow-Credentials 需要设置为 true

*(注意前端请求需要设置 withCredentials = true)

*/

response.setHeader(“Access-Control-Allow-Credentials”, “false”);

结束语

以上文章浅谈了 ajax 以及常用的跨域方案,没有深究到很细节层面的内容。希望对大家有帮助!

关于Ajax以及跨域的一些信息就讲到这里啦!如有疑问欢迎评论区评论或私信我交流~

关注公众号 星期一研究室 ,不定期分享学习干货

如果这篇文章对你有用,记得点个赞加个关注再走哦~