ajax跨域访问遇到的问题及解决方案


Posted in Javascript onMay 23, 2019

Ajax请求一个目标地址为非本域(协议、域名、端口任意一个不同)的web资源,并根据响应获得外部应用数据。比如我们用Ajax访问城市天气预报、IP地址等公共服务接口时,就涉及跨域了。我们请求一个外部服务时,浏览器会基于安全问题拒绝授权访问。

而script、script、iframe标签的src属性就不存在跨域的问题,所以Ajax跨域就是利用这一点以及js对JSON的支持,外部服务只要给Ajax的请求响应一段JS代码或JSON数据,就能被Ajax获取到。

由于安全方面的原因, 客户端js使用xmlhttprequest只能用来向来源网站发送请求,比如在www.readlog.cn下去请求test.readlog.cn的数据,都是不行的。不过,解决办法倒是不少。这里整理一下。

解决方式1 web代理的方式 (on Server A)

由该页面代替用户页面完成交互,从而返回合适的结果。此方案可以解决现阶段所能够想到的多数跨域访问问题,但要求A网站提供Web代理的支持,因此A网站与B网站之间必须是紧密协作的,且每次交互过程,A网站的服务器负担增加,且无法代用户保存session状态。

解决方式2. on-Demand方式 (on Server A)

MYMSN的门户就用的这种方式,不过 MYMSN中不涉及跨域访问问题。在页面内动态生成新的

解决方式3. iframe方式 (on Server A)

查看过醒来在JavaEye上的一篇关于跨域访问的帖子,他提到自己已经用iframe的方式解决了跨域访问问题。数据提交跟获取,采用iframe这种方式的确可以了,但由于父窗口与子窗口之间不能交互(跨域访问的情况下,这种交互被拒绝),因此无法完成对父窗口效果的影响。

在页面内嵌或动态生成指向别的网站的IFRAME,然后这2个网页间可以通过改变对方的anchor hash fragment来传输消息。改变一个网页的anchor hash fragment并不会使浏览器重新装载网页,所以一个网页的状态得以保持,而网页本身则可以通过一个计时器(timer)来察觉自己anchor hash的变化,从而相应改变自己的状态。

解决方式4. 用户本地转储方式 (local)

IE本身依附于windows平台的特性为我们提供了一种基于iframe,利用内存来“绕行”的方案,即两个window之间可以在客户端通过windows剪贴板的方式进行数据传输,只需要在接受数据的一方设置Interval进行轮询,获得结果后清除Interval即可。FF的平台独立性决定了它不支持剪贴板这种方式,而以往版本的FF中存在的插件漏洞又被fixed了,所以FF无法通过内存来完成暗渡陈仓。而由于文件操作FF 也没有提供支持(无法通过Cookie跨域完成数据传递),致使这种技巧性的方式只能在IE中使用。

解决方式5: (其实还是在服务端A用iframe解决了与服务器B通信的问题)

要解决的问题:发生在用户提交网页 URL (还包括 Tag, Notes 等)给bookmark 服务器时。

关于 URL 的提交至少可以有三种方式:

1. 登陆 Bookmark 服务器的提交页面,将要收藏的 URL 通过该页面提交给服务器。
2. 安装浏览器插件,通过插件将 URL 提交给服务器。
3. 从 Bookmark 服务器动态加载 javascript 小工具到当前页面,通过它来完成提交工作。

第一种方式开发起来最简单,但对用户来讲比较麻烦,每次都需要先登陆 Bookmark 服务器才能完成提交;第二种方式我并不熟悉插件开发,而且用户也不喜欢太多的插件堆满自己的浏览器;第三种方式开发难度小,又避免了每次登陆服务器的麻烦,所以最终采用它。第三种方式中动态加载的 javascript 小工具除了需要生成 UI 供用户填写信息( URL , tag , notes 等),当用户点击提交的时候,还要完成与服务器通信的功能。

Javascript 相关文章推荐
JS Timing
Apr 21 Javascript
一段利用WSH修改和查看IP配置的代码
May 11 Javascript
jQuery操作select下拉框的text值和value值的方法
May 31 Javascript
jQuery插件jFade实现鼠标经过的图片高亮其它变暗
Mar 14 Javascript
利用JavaScript的AngularJS库制作电子名片的方法
Jun 18 Javascript
JS iFrame加载慢怎么解决
May 13 Javascript
AngularJS优雅的自定义指令
Jul 01 Javascript
js实现前端分页页码管理
Jan 06 Javascript
Vue组件实例间的直接访问实现代码
Aug 20 Javascript
jQuery利用FormData上传文件实现批量上传
Dec 04 jQuery
layui--js控制switch的切换方法
Sep 03 Javascript
Vue实现鼠标经过文字显示悬浮框效果的示例代码
Oct 14 Javascript
简单了解JavaScript异步
May 23 #Javascript
vue项目添加多页面配置的步骤详解
May 22 #Javascript
vue elementUI table 自定义表头和行合并的实例代码
May 22 #Javascript
微信小程序使用websocket通讯的demo,含前后端代码,亲测可用
May 22 #Javascript
微信小程序登录态和检验注册过没的app.js写法
May 22 #Javascript
element-ui上传一张图片后隐藏上传按钮功能
May 22 #Javascript
微信小程序非跳转式组件授权登录的方法示例
May 22 #Javascript
You might like
浅谈php命令行用法
2015/02/04 PHP
Codeigniter控制器controller继承问题实例分析
2016/01/19 PHP
jquery load事件(callback/data)使用方法及注意事项
2013/02/06 Javascript
详解jQuery插件开发中的extend方法
2013/11/19 Javascript
动态的绑定事件addEventListener方法的使用
2014/01/24 Javascript
JavaScript实现计算字符串中出现次数最多的字符和出现的次数
2015/03/12 Javascript
微信浏览器内置JavaScript对象WeixinJSBridge使用实例
2015/05/25 Javascript
JavaScript实现自动消除按钮功能的方法
2015/08/05 Javascript
jQuery右下角旋转环状菜单特效代码
2015/08/10 Javascript
Angularjs实现搜索关键字高亮显示效果
2017/01/17 Javascript
利用JS实现简单的日期选择插件
2017/01/23 Javascript
记一次webpack3升级webpack4的踩坑经历
2018/06/12 Javascript
taro小程序添加骨架屏的实现代码
2019/11/15 Javascript
快速解决vue2+vue-cli3项目ie兼容的问题
2020/11/17 Vue.js
如何正确解决VuePress本地访问出现资源报错404的问题
2020/12/03 Vue.js
vue+vant 上传图片需要注意的地方
2021/01/03 Vue.js
[02:32]【DOTA2亚洲邀请赛】iceice,梦开始的地方
2017/03/13 DOTA
编写Python脚本来获取Google搜索结果的示例
2015/05/04 Python
Python实现将数据库一键导出为Excel表格的实例
2016/12/30 Python
Python定义一个跨越多行的字符串的多种方法小结
2018/07/19 Python
django框架之cookie/session的使用示例(小结)
2018/10/15 Python
python实现简单日期工具类
2019/04/24 Python
Python爬虫 scrapy框架爬取某招聘网存入mongodb解析
2019/07/31 Python
Tensorflow 多线程设置方式
2020/02/06 Python
Keras自定义实现带masking的meanpooling层方式
2020/06/16 Python
Python本地及虚拟解释器配置过程解析
2020/10/13 Python
uniapp+Html5端实现PC端适配
2020/07/15 HTML / CSS
中国首家奢侈品O2O网购平台:第五大道奢侈品网
2017/12/14 全球购物
C#可否对内存进行直接的操作
2015/02/26 面试题
空中乘务员岗位职责
2014/03/08 职场文书
外语系毕业生求职自荐信
2014/04/12 职场文书
创业计划书之服装
2019/10/07 职场文书
CSS3 制作的彩虹按钮样式
2021/04/11 HTML / CSS
ES6 解构赋值的原理及运用
2021/05/25 Javascript
Sleuth+logback 设置traceid 及自定义信息方式
2021/07/26 Java/Android
Python测试框架pytest高阶用法全面详解
2022/06/01 Python