1.在HTML文档中能够发起HTTP请求的元素有:
<a>,<img>,<link> ,<script>,<iframe><frame>请求HTML文档文件,<form>请求(get/post),<object>请求其他资源文件,音频视频,插件,<source>用于音频视频,从域的概念来讲,HTML中的这些元素,都是可以跨域请求资源的。这些请求都是传统的HTTP请求。
哪些算是跨域:
什么是跨域:我们经常会在页面上使用ajax请求访问其他服务器的数据,此时,客户端会出现跨域问题,跨域问题是由于javascript语言安全限制中的同源策略造成的。简单来说,同源策略是指一段脚本只能读取来自同一来源的窗口和文档的属性,这里的同一来源指的是主机名、协议和端口号的组合,ajax不允许跨域通信。如果尝试从不同的域请求数据,就会出现错误。
例如:
URL | 说明 | 是否允许通信 |
---|---|---|
http://www.a.com/a.js http://www.a.com/b.js | 同一域名下 | 允许 |
http://www.a.com/lab/a.js http://www.a.com/script/b.js | 同一域名下不同文件夹 | 允许 |
http://www.a.com:8000/a.js http://www.a.com/b.js | 同一域名,不同端口 | 不允许 |
http://www.a.com/a.js https://www.a.com/b.js | 同一域名,不同协议 | 不允许 |
http://www.a.com/a.js http://70.32.92.74/b.js | 域名和域名对应ip | 不允许 |
http://www.a.com/a.js http://script.a.com/b.js | 主域相同,子域不同 | 不允许 |
http://www.a.com/a.js http://a.com/b.js | 同一域名,不同二级域名(同上) | 不允许(cookie这种情况下也不允许访问) |
http://www.cnblogs.com/a.js http://www.a.com/b.js | 不同域名 | 不允许 |
怎么解决跨域问题:
思路:web页面可以加载放在任意站点的js、css、图片等资源,不会受到"跨域"的影响,既然我们可以调用第三方站点的js,那么如果我们将数据放到第三方站点的js中不就可以将数据带到客户端了。
方法:JSONP
JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。其核心思想是利用JS标签里面的跨域特性进行跨域数据访问,在JS标签里面存在的是一个跨域的URL,实际执行的时候通过这个URL获得一段字符串,这段返回的字符串必须是一个合法的JS调用,通过EVAL这个字符串来完成对获得的数据的处理。
实例1:
function getJson(data){
console.log(data);
}
function createUrl(){
var script=document.createElement("script");
script.type="text/javascript";
script.src="http://localhost:80/ddxq/DomainPhp?callback=getJson";
document.getElementsByTagName("head")[0].appendChild(script);
}
就是在动态添加一个<script>,通过这个来获取数据。传递的参数是getJson,也就是获取数据后的回调函数的名字。服务器端需要做相应调整,返回可以调用的js代码
<script>
function getJson(data){
console.log(data)
}
</script>
<script src="http://meihua.com/data.php?callback=getJson"></script>
实例2:
function
getJSon
(data){
console.log(data);
}
function
getDomain(){
$.ajax({
url:
'http://localhost:8080/test/DomainSer'
,
crossDomain:
true
,
dataType:
'jsonp'
,
type:
'post'
,
data:{
jsonp:
'callback'
},
jsonpCallback:
'getJSon'
});
}
实例2:
客户端JS:
var url = '';
$.ajax({
type : "get",
async : false,
url :url,
cache : false,
dataType : "jsonp",
jsonp: "callbackparam",
jsonpCallback:"jsonpCallback1",
success : function(json){
alert(json[0].name);
},
error:function(e){
alert("error");
}
});
服务端代码:
String callbackFunName = context.Request["callbackparam"];
context.Response.Write(callbackFunName + "([ { \"name\":\"John\"}])");
jsonp: "callbackparam"
jsonpCallback:"jsonpCallback1"
这两个参数最终会拼接在请求的url后面,变成 url?callbackparam=jsonCallback1
服务端要获取这个参数值:"jsonCallback1" ,拼接在要输出的JSON数据最前面,不然就算请求成功你也只会看到警告:
Resource interpreted as Script but transferred with MIME type text/plain:
实例3:
$.getJSON("http://www.ddxq.com/photos.php?soncallback=?",function(data){
console.log(data)
});
总结:
1.ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是通过HTTP来动态添加<script>标签来调用服务器提供的js脚本。
2.在chrome浏览器里,还可以在服务端设置header信息
context.Response.AddHeader("Access-Control-Allow-Origin", "*");
来达到跨域请求的目的,并且不需要设置ajax参数,以正常ajax请求方式就可以获得数据。
获取更多的文章,欢迎关注微信公众号