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

AJAX和跨域

  • 引言
  • 正文
  • 一、AJAX请求
    • 1、模拟get和post请求
    • 2、封装一个简易的AJAX
  • 二、状态码
    • 1、xhr.readyState
    • 2、xhr.status
  • 三、跨域
    • 1、同源策略
      • (1)同源策略是什么
      • (2)为什么浏览器会有同源策略?
      • (3)同源策略限制内容有哪些?
      • (4)加载图片、js和css时可以无视同源策略
    • 2、跨域解决方案
      • (1)跨域是什么
      • (2)解决跨域的方式
        • 1)JSONP(客户端操作)
        • 2)CORS(服务器操作)
  • 结束语

引言

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时可以无视同源策略

<img src = 跨域的图片地址 />
<link href = 跨域的css地址/>
<script src = 跨域的js地址></script>

如以上代码所示,当我们在加载以上类型的 图片、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以及跨域的一些信息就讲到这里啦!如有疑问欢迎评论区评论或私信我交流~

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.tpcf.cn/news/308028.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

译 | Azure 应用服务中的程序崩溃监控

点击上方蓝字关注“汪宇杰博客”原文&#xff1a;Yun Jung Choi, Puneet Gupta翻译&#xff1a;汪宇杰应用程序崩溃经常发生。崩溃是指代码中的异常未得到处理并终止进程。这些未处理的异常也称为二次机会异常&#xff08;second chance exceptions&#xff09;。当您的应用程序…

解决浏览器存储问题,不得不了解的cookie,localStorage和sessionStorage

浏览器存储方式一、浏览器存储的方式二、cookie、localStorage和sessionStorage1、cookie、localStorage和sessionStorage是什么&#xff1f;&#xff08;1&#xff09;cookie&#xff08;2&#xff09;localStorage&#xff08;3&#xff09;sessionStorage2、cookie、localSt…

使用Seq搭建免费的日志服务

Seq简介Seq是老外开发的一个针对.NET平台非常友好的日志服务。支持容器部署&#xff0c;提供一个单用户免费的开发版本。官网&#xff1a;https://datalust.co/seq使用文档&#xff1a;https://docs.datalust.co/docsSeq主体功能如下所示&#xff1a;支持主流的编程语言&#x…

leetcode27:移除元素(暴力+双指针)

一&#xff1a;题目 二&#xff1a;暴力双指针 1&#xff1a;暴力解法 (1):思路 1.在数组当中 我们想要删除一个元素 得靠覆盖也就是后面的元素往前覆盖其想要删除的元素 但是注意的是我们真实的数组中的元素个数是不变的 因为我们只是将后面的元素移到起前面 并未真正的删除…

三分钟Docker-推送本地镜像到仓库

在上篇文章中&#xff0c;我们完成了应用程序容器化&#xff0c;把webapi项目构建镜像并容器化运行。本文将会演示如何把自己构建的镜像上传到docker官网的仓库和自己私有仓库本地镜像推送到官网的registry1.创建仓库点击Docker Desktop图标->Repositories-》create 跳转到…

你知道304吗?图解强缓存和协商缓存

http协议—常见状态码&#xff0c;请求方法&#xff0c;http头部&#xff0c;http缓存一、http状态码1、引例阐述2、状态码分类3、常见状态码4、关于协议和规范二、http 方法1、传统的methods2、现在的methods3、Restful API&#xff08;1&#xff09;Restful API是什么&#x…

leetcode844. 比较含退格的字符串(栈+双指针)

一:题目 二:思路代码 1:利用栈 (1):思路 1.利用栈 我们将字符串中的单个元素都入栈 当遇到’#的时候将将栈顶元素弹出 (2):上码&#xff08;方法一&#xff09; class Solution { public:/**思路:1.利用栈 我们将字符串中的单个元素都入栈 当遇到#的时候将将栈顶元素弹出*…

efcore技巧贴-也许有你不知道的使用技巧

前言.net 环境近些年也算是稳步发展。在开发的过程中&#xff0c;与数据库打交道是必不可少的。早期的开发者都是DbHelper一撸到底&#xff0c;到现在的各种各样的ORM框架大行其道。孰优孰劣谁也说不清楚&#xff0c;文无第一武无第二说的就是这个理。没有什么最好的&#xff0…

关于前端性能优化问题,认识网页加载过程和防抖节流

前端性能优化—网页加载过程、性能优化方法、防抖和节流一、网页加载过程1、加载资源的形式2、加载资源的过程3、渲染页面的过程4、关于window.onload 和 DOMContentLoaded二、性能优化1、性能优化原则2、性能优化的方法3、让加载更快4、让渲染更快三、防抖和节流1、防抖 debou…

javax.net.ssl.SSLHandshakeException: No appropriate protocol

一:报错 二:解决 找到jdk 1.8安装目录&#xff0c;找到C:\Program Files\Java\jre里面的lib\security 下面有个java.security将jdk.tls.disabledAlgorithms后面的SSLv3, TLSv1, TLSv1.1都删除掉.&#xff08;大概位置是在700多行&#xff09; 三:上方并未解决的 我的jdk是这…

『软件工程9』结构化系统分析——解决软件“做什么”问题

结构化系统分析——解决软件“做什么”问题一、系统分析的任务和过程1、系统分析的任务2、系统分析的过程&#xff08;1&#xff09;问题识别&#xff08;2&#xff09;分析与综合&#xff08;3&#xff09;编制文档&#xff08;4&#xff09;系统分析评审二、结构化分析方法1、…

.NET5.0 Preview 8 开箱教程

.NET5.0 Preview 8 开箱教程前言首先&#xff0c;看到 .NET5.0 Preview 8 发布后&#xff0c;作为一枚基层应用开发人员&#xff0c;很想要体验一下新版本的魅力&#xff1b;这可能就是程序员对新技术的一种执着吧。其实从官方宣布 .NETCore 将更名为 .NET5 开始&#xff0c;我…

leetcode977. 有序数组的平方(暴力+双指针)

一:题目 二:暴力双指针 1:暴力 class Solution { public:vector<int> sortedSquares(vector<int>& nums) {vector<int> v;for(int num : nums){int temp pow(num,2);v.push_back(temp);} sort(v.begin(),v.end());return v;} };2:双指针 思路:1.利…

『软件工程10』结构化系统分析:数据流图和字典案例分析

结构化系统分析——数据流图和数据字典案例分析一、数据流图案例分析1、案例1&#xff1a;商店业务管理系统2、案例2&#xff1a;学籍管理系统3、案例3&#xff1a;大型企业数据中心二、数据字典案例分析1、案例1&#xff1a;学籍管理系统三、写在最后接 上一篇文章的内容&…

MongoDB最新4.2.7版本三分片集群修改IP实操演练

背景重新组网&#xff0c;需要对现有MongoDB分片集群服务器的IP进行更改&#xff0c;因此也需要对MongoDB分片集群的IP也进行相应的更新&#xff0c;而MongoDB分片集群的IP修改不能单纯的通过配置来进行&#xff0c;需要一番折腾后才能正常更新&#xff0c;这里对整个MongoDB集…

浅谈Web前端安全策略xss和csrf,及又该如何预防?

Web前端安全策略xss和csrf的攻击和防御一、XSS跨站请求攻击1、什么是XSS2、场景模拟3、XSS的攻击类型4、如何防御XSS二、XSRF跨站请求伪造1、什么是csrf2、场景模拟&#xff08;1&#xff09;场景一&#xff08;2&#xff09;场景二3、CSRF的特点4、CSRF攻击方式5、CSRF常见的攻…

leetcode209. 长度最小的子数组(暴力+滑动窗口)

一:题目 二:暴力滑动窗口 1:暴力解法 class Solution { public:int min (int a ,int b){return a < b ? a : b;}int minSubArrayLen(int target, vector<int>& nums) {int minx 100001;for(int i 0; i < nums.size(); i){vector<int> v;int sum nu…

做权限认证,还不了解IdentityServer4?不二话,赶紧拥抱吧,.NET Core官方推荐!...

目前大多数的应用程序或多或少看起来是上图所示这样的&#xff0c;最常见的交互场景有&#xff08;浏览器与Web应用程序、Web应用程序与WebApi通讯、本地应用程序狱WebApi通讯、基于浏览器的应用程序与WebApi 通讯、基本服务器的应用程序与WebApi通讯、WebApi与WebApi通讯&…

leetcode 904:水果成篮(滑动窗口)

一:题目 二:思路 1.用两个篮子装进两个数&#xff0c;后面只能装入这两个相同的数,并统计个数;如果遇到其他数,则重新开始计数&#xff0c; 这里的重新开始计数指的是在去除第一个篮子中所装进的数 2.滑动窗口来做 滑动窗口的起始位置为:数组的起始位置 滑动体为 统计的个数 滑…

真・WPF 按钮拖动和调整大小

真・WPF 按钮拖动和调整大小独立观察员 2020 年 8 月 29 日手头有个 Winform 程序&#xff0c;是使用动态生成按钮&#xff0c;然后拖动、调整大小&#xff0c;以此来记录一些坐标数据&#xff0c;最后保存坐标数据的。在数据量&#xff08;按钮数量&#xff09;比较小的时候是…