Ajax 跨域难题 - 原生 JS 和 jQuery 的实现对比
- 讲解顺序:
- AJAX 的概念及由来
- JS 和 jQuery 中的 ajax
- 浏览器机制
- AJAX 跨域
AJAX 的概念
- 在讲解 AJAX 的概念之前,我先提一个问题。
这是一个典型的 B/S 模式。
PS. B/S结构(Browser/Server,浏览器/服务器模式),是WEB兴起后的一种网络结构模式,WEB浏览器是客户端最主要的应用软件。这种模式统一了客户端,将系统功能实现的核心部分集中到服务器上,简化了系统的开发、维护和使用。客户机上只要安装一个浏览器
B/S 模式
- 优点:一个服务器可以响应多个客户端
- 缺点:短链接(与 C/S 相反)
- 特点:客户端主动去请求(request),服务器端被迫去响应(response)
这一点很重要
- 好处:大大减少了服务器的资源
- 结论:服务器永远没办法主动告诉客户端一些信息
在这张图中,左侧是菜单,很早之前的做法是点击刷新按钮会对整个页面进行刷新,这样做的弊端是什么?如何不使用 AJAX 进行局部刷新?
- 弊端
- I/O 网络吞吐量过大
- 网页加载慢
- 耗内存及 CPU
- 局部刷新
- 很 low,但是只有唯一的方法:iframe
- 虽然是局部刷新,但是是局部整体刷新
那么有什么办法能进行数据实时推送(例如股票价格)?
于是诞生了这几个方法。
- 轮询机制(依旧很占服务器资源,low)
- 服务器推送(提一下,想了解的下次,不是这次要讲的东西)
那么,iframe 最大的缺点是什么?
- 外面的 window 和 iframe 的 window 不是一个对象,也就是说,不在一个 DOM 树中!这样的话,外面内容和里面内容交互起来特别繁琐。
- AJAX 解决了这个问题。
了解 AJAX 之前先要了解一下前后端的交互过程。
大家慢慢看……
JS 和 jQuery 中的 ajax
- AJAX 全称:即“Asynchronous JavaScript And XML” (代表一种格式,比如:json、HTML、XML、text、jsonp等等)
- AJAX 的核心对象是 XMLHttpRequest 对象
- 查看方法(就是 network 里的 XHR)
- IE7及其他浏览器:XMLHttpRequest
- IE6及以下:ActiveXObject
// 简单的ajax请求
var xhr = new XMLHttpRequest();// 创建
xhr.onreadystatechange = function() {// onreadystatechange 不是检测方法,而是状态改变后更新的状态
if (xhr.status == 200) {
/*
普及一下常用的状态码
200:ok,服务器成功返回数据
400:Bad Request,语法错误
401:请求需要认证
404:not found,找不到页面
500:服务器遇到意外错误
503:服务器正在维护或者过载无法完成请求
其他百度去
*/
if (xhr.readyState == 4) {
/*
xhr.readyState 是 ajax 状态
普及一下这个4是什么意思:
0:创建服务
1:打开服务
2:发送服务
3:服务器响应
4:加载成功
*/
var data = JSON.parse(xhr.responseText);// responseText 是返回的文本或对象
}
} else {
// 如果不是正常返回
console.log("数据返回失败!状态码" + xhr.status + "状态信息:" + xhr.statusText)
// xhr.statusText是浏览器的错误信息,因为跨浏览器的时候,可能不太一致,不建议直接使用它
}
}
xhr.open("post", "list.json?rand="+new Date(), true);// 打开,最后一个 bool 代表是否异步,这一步仅仅只配置了 ajax 的基本信息,而并没有对服务器请求
// rand=new Date()是为了让每一次请求 url 都不同,用来区分缓存
xhr.setRequestHeader("Content-Type","application/www-x-form-urlencoded");
xhr.send(null);// 向服务器发送请求
jQuery 的 ajax 实际上就是封装了上面的代码
$.ajax({
type:"get",
dataType: "json",
url: url,
async: true,
success: function(){},
error: function(){}
})
下面用 chrome 和 Firefox 来演示跨域问题。
浏览器机制
- 用 原生 AJAX 进行跨域请求,会发现报错了,仔细分析错误
- 得到结论:AJAX 本身是可以跨域的,但是浏览器的同源策略机制,限制了 XMLHttpRequest 请求,导致无法跨域,所以 AJAX 在浏览器中跨域是一个伪命题,而 AJAX 不是无法跨域的主谋。
- 以下几种情况会被浏览器视为不安全,而直接进行拦截
- 同源规则:同域名、端口、协议(只针对 XMLHttpRequest)
- www.a.com 和 a.com实际是配置的两个域名
编号 | url | 说明 | 是否允许通信 |
---|---|---|---|
1 | http://www.a.com/a.js http://www.a.com/b.js |
同一域名下 | 允许 |
2 | http://www.a.com/a/a.js http://www.a.com/b/b.js |
同一域名不同文件夹 | 允许 |
3 | http://www.a.com:8080/a.js http://www.a.com:9090/a.js |
同一域名不同端口号 | 不允许 |
4 | http://www.a.com/a.js https://www.a.com/b.js |
同一域名不同协议 | 不允许 |
5 | http://www.a.com/a.js http://192.168.4.158/b.js |
域名与域名对应的ip地址 | 不允许 |
6 | http://www.a.com/a.js http://github.a.com/b.js |
主域名相同,子域名不同 | 不允许 |
7 | http://www.a.com/a.js http://a.com/b.js |
同一域名,不同二级域名(同上) | 不允许(cookie这种情况下也不允许访问) |
8 | http://www.a.com/a.js http://www.b.com/b.js |
不同域名 | 不允许 |
AJAX 跨域
- 代理
- 向服务器发送对应的 url,服务器在后台做了一个代理,前端只需要访问A的服务器也就相当与访问了B的服务器,比如在A(
www.a.com/sever.php
)和B(www.b.com/sever.php
)各有一个服务器,A的后端(www.a.com/sever.php
)直接访问B的服务,然后把获取的响应值返回给前端。这种代理属于后台的技术,所以不展开叙述。
- 向服务器发送对应的 url,服务器在后台做了一个代理,前端只需要访问A的服务器也就相当与访问了B的服务器,比如在A(
- JSONP
- 说白了就是利用同源策略的漏洞,利用创建标签的形式进行加载。
- JS 中的实现
//创建一个script元素
var Scr = document.reateElement('script');
//声明类型
Scr.type='text/javascript';
//添加src属性,引入跨域访问的url
Scr.src=url;
//在页面中添加新创建的script元素
document.getElementsByTagName('body')[0].appendChild(Scr)
- jQuery 中的实现:
$.ajax({
url: 'http://192.168.1.114/yii/demos/test.js', //不同的域
type: 'GET', // jsonp模式只有GET是合法的
data: {
'action': 'aaron'
}, // 预传参的数组
dataType: 'jsonp', // 数据类型
jsonp: 'backfunc', // 指定回调函数名,与服务器端接收的一致,并回传回来
})
整个流程就是:
客户端发送一个请求,规定一个可执行的函数名(这里就是jQuery做了封装的处理,自动帮你生成回调函数并把数据取出来供success属性方法来调用,不是传递的一个回调句柄),服务端接受了这个backfunc函数名,然后把数据通过实参的形式发送出去
其实就是jquery内部会转化成http://192.168.1.114/yii/demos/test.js?backfunc=jQuery2030038573939353227615_1402643146875&action=aaron
然后动态加载
<script type="text/javascript" src="http://192.168.1.114/yii/demos/test.js?backfunc=jQuery2030038573939353227615_1402643146875&action=aaron"></script>
- XHR2
“XHR2” 全称 “XMLHttpRequest Level2” 是HTML5提供的方法,对跨域访问提供了很好的支持,并且还有一些新的功能。
IE10以下的版本都不支持
只需要在服务器端头部加上下面两句代码:
header( "Access-Control-Allow-Origin:*" );
header( "Access-Control-Allow-Methods:POST,GET" );
Ajax 跨域难题 - 原生 JS 和 jQuery 的实现对比的更多相关文章
- ajax-解决跨域请求(基于js,jQuery的josnp,设置响应头的cors)
同源策略 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以说Web是构建在同源策略基础之上的 ...
- 关于AJAX跨域和原生AJAX CORS跨域解决
项目需求要在别人的域名下调用自己的接口,因为浏览器的同源策略是不允许不同域名下之间的信息交换,那就意味着要跨域处理 参考博客 :https://blog.csdn.net/Ulricalin/arti ...
- 原生JS与jQuery操作DOM对比
一.创建元素节点 1.1 原生JS创建元素节点 document.createElement("p"); 1.2 jQuery创建元素节点 $('<p></p&g ...
- JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)
这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...
- jquery ajax跨域的完美解决方法(jsonp方式)
ajax跨域请求的问题,JQuery对于Ajax的跨域请求有两类解决方案,不过都是只支持get方式,接下来为大家详细介绍下客户端JQuery.ajax的调用代码 今天在项目中需要做远程数据加载 ...
- 原生js替换jQuery各种方法-中文版
原文https://github.com/nefe/You-D... 原生JS与jQuery操作DOM对比 You Don't Need jQuery 前端发展很快,现代浏览器原生 API 已经足够好 ...
- 原生js 与 jQuery对比
1.原生JS与jQuery操作DOM对比 : https://www.cnblogs.com/QianBoy/p/7868379.html 2.比较jQuery与JavaScript的不同功能实 ...
- 前端跨域问题相关知识详解(原生js和jquery两种方法实现jsonp跨域)
1.同源策略 同源策略(Same origin policy),它是由Netscape提出的一个著名的安全策略.同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正 ...
- NodeJ node.js Jquery Ajax 跨域请求
Jquery + Ajax 跨域请求 说白了就是前台请求ajax数据(JSON)但是请求的数据不在本地的绝对路径下,接口数据 是没有这个安全性的我对外公开的接口数据,只要你找到接口你就可以使用里面的数 ...
随机推荐
- poj3255 Roadblocks 次短路
Roadblocks Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10098 Accepted: 3620 Descr ...
- SQLSERVER中文日期varchar格式转换成datetime格式
因项目要求,需要把SQLSERVER一张客户表的数据同步到oracle库的一张客户表,但两张表有时间类型不一致,需要进行转换 如下: SELECT CUSTCODE,AgreementValidity ...
- hihoCoder #1117 战争年代
题目大意 对一棵树的节点染色.初始时每个点都染成颜色 $0$,然后进行 $m$ 轮操作.第 $i$ 轮操作:从 $[0,d_i]$ 中随机选出一个整数 $d$,将距离点 $x_i$ 不超过 $d$ 的 ...
- 【bzoj3098】Hash Killer II 生日悖论
这天天气不错,hzhwcmhf神犇给VFleaKing出了一道题:给你一个长度为N的字符串S,求有多少个不同的长度为L的子串.子串的定义是S[l].S[l + 1].… S[r]这样连续的一段.两个字 ...
- Python基础教程总结(二)
上周总结了一下Python的一些基本数据类型和用法.这次总结一下4-9章的内容,完后,赶紧学以致用吧. 5. 第四章——字典:当索引不好用时 字典是Python中唯一内建的映射类型.字典中的值并没有特 ...
- 第一次用写一个3d轮播
2016-07-11gallery 3d html <!doctype html><html lang="en"><head> <met ...
- es6总结 (五)--函数扩展
- hdu 4311 & 4312 Meeting point 曼哈顿距离之和最小
hdu 4311 题意 平面上\(n(n\leq 1e5)\)个点,找一个点到其它所有点的曼哈顿距离之和最小. 思路 如果是找一个坐标使得所有点到其曼哈顿距离之和最小,那么将\(n\)个横坐标排个序, ...
- 从网上搜集的X86 显示 int 10H
INT 10H 是由 BIOS 对屏幕及显示器所提供的服务程序,而后倚天公司针对倚天中文提供了许多服务程序,这些服务程序也加挂在 INT 10H 内.使用 INT 10H 中断服务程序时,先指定 AH ...
- 总结下常用js中的小语法和技巧
1,数组对象遍历 对一个级数对象进行遍历,取出每个值 var arr={ "result":[ {"time":"2018-10-24 12:12:1 ...