JSONP方法解决跨域请求
Ajax跨域请求的问题
跨域:跨域名, 一个域名下的文件去请求了和他不一样的域名下的资源文件(注意是请求文件,而不是数据接口),那么就会产生跨域请求,下面来写一个ajax来跨域请求的例子
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<script>
window.onload = function() {
//ajax跨域请求限制
var oBtn = document.getElementById('btn');
oBtn.onclick = function() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if ( xhr.status == 200 ) {
alert( xhr.responseText );
}
}
}
xhr.open('get', 'http://api.douban.com/book/subjects?q=javascript&alt=json&max-results=1', true);
xhr.send();
}
}
</script>
</head> <body>
<input type="button" value="按钮" id="btn" />
</body>
</html>
结果可以看到,报错了,如果该域名的服务器设置了这个域名为白名单,就可以访问,就相当于电话白名单,才可以进行通话
像这样的需要跨域请求的情况下,可以在当前项目中创建一个后台服务,使用这个后台服务去请求不同域名下的资源(不涉及跨域请求的问题),然后后台服务跟前端放在一起(同域名)转发给前端,这样的话也可以解决跨域请求的问题,这个后台服务就相当于中转站,如果没有这个后台服务,那么就前端直接使用跨域去请求,比如下面的jsonp
跨域请求的解决方法(Jsonp : json with padding)
jsonp的实现原理:
利用script标签,用script标签加载资源是没有跨域问题的,通过script标签的一个src属性加载(包含指定的外部文件),可以跨域包含 ,被包含的资源可以是任何类型的文件(可以是txt,php等) ,他只关注被包含的文件的内容是否是合法的JS,否则是会报错的),也就是说利用script标签来拿到其他域名下的接口数据,但是有个问题就是说,拿到的这个数据可能是一个没有名字的数组,那么即使拿到了没没法办使用,如果这个数组在文件中有声明一个变量来保存,那么通过script标签拿到后是可以通过这个变量来使用的,但是有个问题就是这个变量是全局的(js代码设计过程中尽量少用全局变量)
在资源加载进来之前定义好一个函数,这个函数接收一个参数(数据),函数里面利用这个参数做一些事情,然后需要的时候通过script标签加载对应远程文件资源,当远程的文件资源被加载进来的时候,就会去执行我们前面定义好的函数,并且把数据当作这个函数的参数传入进去
需要注意的是fn这个回调函数的名字需要跟请求文件中的fn这个函数名字相同
function fn(data) {
alert(data);
}
</script>
<script src="2.txt"></script>
在实际项目中,需要按需加载,而不是页面一渲染就去加载这个请求,比如下面通过点击事件动态创建script标签并且将src资源引入
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<script>
function fn(data) {
alert(data);
}
</script>
<script>
window.onload = function() {
var oBtn = document.getElementById('btn');
oBtn.onclick = function() {
//当按钮点击的时候再去加载远程资源,让他执行
var oScript = document.createElement('script');
oScript.src = '2.txt';
document.body.appendChild(oScript);
}
}
</script>
</head>
<body>
<input type="button" id="btn" value="按钮" />
</body>
</html>
百度搜索下拉提示实例
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<style>
#q {width: 300px; height: 30px; padding: 5px; border:1px solid #f90; font-size: 16px;}
#ul1 {border:1px solid #f90; width: 310px; margin: 0;padding: 0; display: none;}
li a { line-height: 30px; padding: 5px; text-decoration: none; color: black; display: block;}
li a:hover{ background: #f90; color: white; }
</style>
<script>
function maiov(data) {
console.log(data)
var oUl = document.getElementById('ul1');
var html = '';
if (data.s.length) {
oUl.style.display = 'block';
for (var i=0; i<data.s.length; i++) {
html += '<li><a target="_blank" href="http://www.baidu.com/s?wd='+data.s[i]+'">'+ data.s[i] +'</a></li>';
}
oUl.innerHTML = html;
} else {
oUl.style.display = 'none';
}
}
window.onload = function() {
var oQ = document.getElementById('q');
var oUl = document.getElementById('ul1');
oQ.onkeyup = function() {
if ( this.value != '' ) {
var oScript = document.createElement('script');
oScript.src = 'http://suggestion.baidu.com/su?wd='+this.value+'&cb=maiov';//cd也就是回掉函数,用于获取数据的函数
document.body.appendChild(oScript);
} else {
oUl.style.display = 'none';
}
}
}
</script>
</head>
<body>
<input type="text" id="q" />
<ul id="ul1"></ul>
</body>
</html>
上面接口中可以自己定义一个回调函数名,上面叫做maiov,当拿到数据时候,可以看到方法名也叫做maiov
豆瓣搜索实例
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<style>
#q {width: 300px; height: 30px; padding: 5px; border:1px solid #f90; font-size: 16px;}
dl {border-bottom: 1px dotted #000;}
dt {font-weight: bold;}
</style>
<script>
function fn1(data) {
var oMsg = document.getElementById('msg');
var oList = document.getElementById('list');
console.log(data);
oMsg.innerHTML = data.title.$t + ' : ' + data['opensearch:totalResults'].$t; var aEntry = data.entry;
var html = '';
for (var i=0; i<aEntry.length; i++) {
html += '<dl><dt>'+ aEntry[i].title.$t +'</dt><dd><img src="'+ aEntry[i].link[2]['@href'] +'" /></dd></dl>';
}
oList.innerHTML = html;
}
window.onload = function() {
var oQ = document.getElementById('q');
var oBtn = document.getElementById('btn');
var oMsg = document.getElementById('msg');
var oList = document.getElementById('list'); oBtn.onclick = function() {
if ( oQ.value != '' ) {
var oScript = document.createElement('script');
oScript.src = 'http://api.douban.com/book/subjects?q='+oQ.value+'&alt=xd&callback=fn1';
document.body.appendChild(oScript);
} //http://api.douban.com/book/subjects?q='+oQ.value+'&alt=xd&callback=fn1&start-index=(当前页*每页显示的条数)&max-results=10(每页显示的条数) } }
</script>
</head> <body>
http://www.douban.com/service/apidoc/reference/
<input type="text" id="q" /><input type="button" id="btn" value="搜索" />
<p id="msg"></p>
<hr />
<div id="list"></div>
</body>
</html>
JSONP方法解决跨域请求的更多相关文章
- js中ajax如何解决跨域请求
js中ajax如何解决跨域请求,在讲这个问题之前先解释几个名词 1.跨域请求 所有的浏览器都是同源策略,这个策略能保证页面脚本资源和cookie安全 ,浏览器隔离了来自不同源的请求,防上跨域不安全的操 ...
- 外部调用mvc的api方法时,如何解决跨域请求问题?
首先,创建一个mvc项目(包含webapi),我们模拟一个场景 1)在项目的Controller 创建一个WeiXinApiController public class WeiXinApiContr ...
- Django使用jsonp和cors解决跨域请求问题
1.使用jsonp的方式解决跨域请求的问题 我启动两个django项目,然后使用的端口不一样,在项目1中通过ajax发请求给项目2,然后接受项目2发送过来的数据 先看项目1的ajax的代码 $(&qu ...
- 使用SpringMVC的@CrossOrigin注解解决跨域请求问题
跨域问题,通俗说就是用ajax请求其他站点的接口,浏览器默认是不允许的.同源策略(Same-orgin policy)限制了一个源(orgin)中加载脚本或脚本与来自其他源(orgin)中资源的交互方 ...
- SpringBoot 中解决跨域请求
CORS 理解 同源策略是web浏览器实现的一个重要的安全概念,它防止JavaScript代码对不同的来源(例如,不同的域)发出请求,而不是它所服务的来源.虽然同源策略有效地防止来自不同来源的资源,但 ...
- SpringBoot解决跨域请求拦截
前言 同源策略:判断是否是同源的,主要看这三点,协议,ip,端口. 同源策略就是浏览器出于网站安全性的考虑,限制不同源之间的资源相互访问的一种政策. 比如在域名https://www.baidu.co ...
- Ajax 调用webservice 解决跨域请求和发布到服务器后本地调用成功外网失败的问题
webservice 代码 /// <summary> /// MESService 的摘要说明 /// </summary> [WebService(Namespac ...
- XMLHttpRequest.withCredentials 解决跨域请求头无Cookie的问题
查看原文 XMLHttpRequest.withCredentials 属性是一个Boolean类型,它指示了是否该使用类似cookies,authorization headers(头部授权)或者 ...
- 关于试用jquery的jsonp实现ajax跨域请求数据的问题
我们在开发过程中遇到要获取另一个系统数据时,就造成跨域问题,这就是下文要说的解决办法: 先我们熟悉下json和jsonp的区别: 使用AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交 ...
随机推荐
- [转]解决ssh登录后闲置时间过长而断开连接
本文转自: 转载自博客园wanghetao的博客 我们通过终端连接服务器时,当鼠标和键盘长时间不操作,服务器就会自动断开连接,我们还的需要重新连接,感觉很麻烦,总结一下解决此问题的方法 方法一 修改/ ...
- 在jQuery定义自己函数
刚才有学习<在jQuery定义自己的扩展方法函数>http://www.cnblogs.com/insus/p/3415312.html .现在想练习一下定义自定义函数.经重构之后,还是发 ...
- C++为啥要使用new
1.为什么要有new? 为什么要有new?为什么要动态创建对象?为什么有时候不用new,有时候又用new,比如: // Cocos2d-x3.x的Value类,大家都很熟悉了 Value v = Va ...
- Http请求处理流程
本文结构: 一.HTTP请求处理流程的基础 1.网络分层 因特网TCP/IP分层模型共有五层:应用层.传输层.网络层.网络接口层和物理层.这种分层模型不同于OSI七层参考模型,但是,是实际使用中采用的 ...
- thinkphp 百度编辑器和layer简单用法
百度编辑器1.4.3.3和layer插件简单案例 :后台单页面管理 增删改查操作 此处为默认图片保存路径,如果要修改保存路径,需要修改config文件. 添加页. <extend name=&q ...
- [日常] Go语言圣经-匿名函数习题
Go语言圣经-匿名函数1.拥有函数名的函数只能在包级语法块中被声明,通过函数字面量(function literal),我们可绕过这一限制,在任何表达式中表示一个函数值2.通过这种方式定义的函数可以访 ...
- java设计模式(一)【六大原则】
开发一个系统并不是一件困难的事,但是为何维护好一个系统却是一件让人头疼不以的事? 在笔者的观念中这一切都源自于需求. 如果在软件开发完成之后,需求就不再改变,那大部分程序都不需要维护了.但是, ...
- 【学习笔记】--- 老男孩学Python,day4 编码,数据类型,字符串方法
今日主要内容 1. 编码 1. 最早的计算机编码是ASCII. 美国人创建的. 包含了英文字母(大写字母, 小写字母). 数字, 标点等特殊字符!@#$% 128个码位 2**7 在此基础上加了一位 ...
- 手机网页meta,添加使其兼容各种浏览器
虽然手机不像电脑那样会有各种低版本的浏览器,但写手机端网页也是需要注意的: <!-- 优先使用 IE 最新版本和 Chrome --> <meta http-equiv=" ...
- javascript预编译的过程
预编译的两种情况 全局: 1.全局 直接是script标签中的代码,不包括函数执行执行前:1.首先生成一个GO(global object)对象,看不到,但是可以模拟出来用来分析2.分析变量声明,变量 ...