跨域:当协议、主域名、子域名、端口号中任意一个不相同时都不算同一个域,而在不同域之间请求数据即为跨域请求。解决方法有以下几种(如有错误欢迎指出)以请求图片url为例:

1.通过XMLHttpRequest对象实现(IE10以下不支持)

XMLHttpRequest2.0已经实现了对CORS的原生支持,只需要在访问资源的时候使用绝对URL即可,需要在服务器端将头信息“Access-Control-Origin"设为”*“或当前域名的地址:

html&javascript:

     <button id="btn">load</button>
<div id="process"></div>
<div id="img"></div> <script>
var btn = document.getElementById('btn'),
pro = document.getElementById('process'),
pic = document.getElementById('img'); btn.onclick = function() { var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() { if(xhr.readyState == 4 && xhr.status == 200){

var img = document.createElement('img');
img.src = JSON.parse(xhr.responseText).src;
pic.appendChild(img);
}
}
xhr.open('GET','http://127.0.0.1:8085/AJAX/ajax/server.php',true);
xhr.send(null);
}
</script>

这个例子是在本地测试的,html文件所在的位置是localhost:8085下,虽然127.0.0.1也是指的localhost,但他们也不是同一个域,可以利用这两个地址来模拟跨域请求。

php:

<?php
header("Content-Type:text/plain");
header("Access-Control-Allow-Origin:http://localhost:8085");//设置头部,不设置的话请求会被拒绝
echo '{"src":"http://www.pinkbluecp.cn/face_alignment/img/picture.jpg"}';
?>

post请求也差不多:

btn.onclick = function() {
if(typeof XMLHttpRequest != 'undefined'){
var xhr = new XMLHttpRequest();
}else if(typeof ActiveXObject != 'undefined'){
var xhr = new ActiveXObject("Microsoft.XMLHTTP");
} xhr.onreadystatechange = function() {
console.log(1)
if(xhr.readyState == 4 && xhr.status == 200){
console.log(2)
pic.innerHTML = xhr.responseText;
}
}
xhr.open('POST','http://127.0.0.1:8085/AJAX/ajax/server.php',true);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); //需要设置下头部
var str = 'active=login';
xhr.send(str);

php

<?php
header("Content-Type:text/plain");
header("Access-Control-Allow-Origin:http://localhost:8085"); if($_POST['active'] == 'login'){
echo 'success';
}else {
echo "error";
}
?>

发送数据需要设置一下头部的Content-Type字段。

2.IE(8-10)中实现CORS:

IE8中引入了XDomainRequest对象,该对象和XHR相似,但它能实现安全可靠的跨域通信,不过在IE11中已经无法使用了。

 var btn = document.getElementById('btn'),
pro = document.getElementById('process'),
pic = document.getElementById('img'); btn.onclick = function() {
var xhr = new XDomainRequest();
xhr.onload = function() {
var img = document.createElement('img');
console.log(xhr.responseText)
// img.src = JSON.parse(xhr.responseText).src;
img.src = xhr.responseText;
console.log(img.src);
pic.appendChild(img);
};
xhr.onerror = function() { //XDR无法确定响应状态,需要添加onerror来检测错误
alert("Error!");
}
xhr.open('GET','http://127.0.0.1:8085/AJAX/ajax/server.php'); //该对象的的请求都是异步,没有第三个参数
xhr.send(null);
}

XDR与XHR不同之处在于:

a. cookie不会随请求发送,也不会随响应返回

b. 只能设置请求头中的Content-Type字段

c. 不能访问响应头部信息

d. 只支持GET和POST请求

两者的方法也略有不同,XDR的open方法只有异步一种状态,所以只要传两个参数method和url,在请求返回之后会触发load事件,但无法获取响应状态码,所以想判断请求是否成功只能添加error事件。它也可以和XHR一样添加超时。

关于XDR的post请求,虽然js高编上有介绍,但是在多次尝试后发现已经行不通了,高编上说XDR有专门的属性contentType来设置请求头信息,但在浏览其中会报错:

无法进行设置contentType的操做,后来查阅了一下这篇博客,貌似XDR已经无法在设置请求头了,详情可以去看原博。

3. 实现跨浏览器的CORS

js高编上有一段实现跨浏览器的CORS实现函数:

    <button id="btn">load</button>
<div id="process"></div>
<div id="img"></div> <script>
var btn = document.getElementById('btn'),
pic = document.getElementById('img'); btn.onclick = function() {
console.log(1);
var xhr = createCORS('GET','http://127.0.0.1:8085/AJAX/ajax/server.php');
if(xhr){
console.log(2)
xhr.onload = function(){
console.log(3)
var img = document.createElement('img');
img.src = xhr.responseText;
pic.appendChild(img);
};
xhr.onerror = function() {
alert("Error");
};
xhr.send(null);
}
} function createCORS(method,url){ //参考js高编
console.log('fun')
var xhr = new XMLHttpRequest();
if('withCredentials' in xhr){ //检测是否含有凭据属性
xhr.open(method,url,true);
}else if(typeof XDomainRequest != 'undefined'){ //兼容ie
xhr = new XDomainRequest();
xhr.open(method,url);
}else {
xhr = null;
}
return xhr;
}
</script>

除了IE10-外所有浏览器都有withCredentials属性,所以可以根据这个属性来判断是否支持XMLHttpRequest2.0.

4.图片Ping

图片Ping就是利用图片的src可以使用跨域资源的特性来实现,但是只能实现简单的单向请求,在img的src中传入一个其他域的url并附带一些参数。

5.JSONP

JSONP和图片Ping很相似,也是利用script标签中的链接不受同源限制可以向不同域传递信息,但它传递的是一个已经存在的回调函数,服务器接收到后,将响应数据传入该回调函数并执行该函数从而达到获取数据的目的。

先来看下<script>标签中传入src得到的是什么:

<script src="test.txt"></script>

在src中传入一个文本文件

浏览器中报语法错误,hello world这个变量未定义,服务器响应的数据就时test.txt的内容,而script把这段纯文本当作js代码来解析,当在test.txt中将这段文字加上单引号后:

浏览器不报错了,因为把它当作字符串来解析了。现在把链接换成一个php文件:

php

<?php
echo "Hello World!";
?>

结果一样,浏览器同样也会报错,加上引号后同样也不报错,如果这时服务器端返回的是一个函数名,而该页面正好又有一个同名函数会怎样:

php:

<?php
echo "callback('hello world')";
?>

html

<body>
<script>
function callback(res){
alert(res);
}
</script>
<script src="jsonp.php"></script>
</body>

结果:

callback函数被执行了,因为后台的响应数据被script标签当作js代码执行了,所以这就能理解jsonp的原理了,利用这个回调函数可以获得后台传来的数据:

html:

<body>
<script>
function jsonp(res){
for(var i in res){
console.log("key:"+i+";value:"+res[i]);
}
}
</script>
<script src="jsonp.php?callback=jsonp"></script> //可动态创建
</body>

php:

<?php
$str = '{"name":"Lee","age":20}';
$callback = $_GET['callback'];
echo $callback."($str)";
?>

上面一个简单的例子展示了jsonp如何用回调函数获取服务器响应的json数据:

JSONP的有点在于可以访问到服务器的响应文本,不过缺点就是要从其他域加载代码执行,必须要保证其他域的安全性,不然可能响应信息中会附带恶意脚本,还有一点就是无法确定请求是否失败,即使失败也不会有提示。

6.iframe跨域

iframe跨域与jsonp相似,也利用了src不受同源限制的特性。当A域下的x.html页面要访问B域下的y.html中的信息可以通过A域下的z.html页面作为代理来获取信息:

x.html:

 <!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
</head> <body>
<iframe src="http://127.0.0.1:8085/AJAX/ajax/proxya.html" style="display: none"></iframe>
<p id="getText"></p>
<script>
function callback(text){
text = JSON.parse(decodeURI(text));
document.getElementById("getText").innerHTML= '姓名:' + text.name + '; 年龄:' + text.age;
}
</script>
</body>
</html>

y.html:

 <!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
</head> <body>
<iframe id="myfarme" src="###"></iframe>
<script>
window.onload = function(){
var text = '{"name":"cheng","age":22}';  //存储一个json格式的数据
document.getElementById('myfarme').src="http://localhost:8085/AJAX/ajax/proxyb.html?content="+encodeURI(text); //将数据传个代理页面处理,此时src中的地址不受同源限制,与jsonp相似
}
</script>
</body>
</html>

z.html:

 <!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
<script>
window.onload = function(){
var text = window.location.href.split('=')[1];  //通过分解url获取y.html传来的参数
top.callback(text);  //调用x.html的callback函数
}
</script>
</head> <body>
</body>
</html>

JSONP、图片Ping、XMLHttpRequest2.0等跨域资源请求(CORS)的更多相关文章

  1. 004. 前端跨域资源请求: JSONP/CORS/反向代理

    1.什么是跨域资源请求? https://www.cnblogs.com/niuli1987/p/10252214.html 同源: 如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有 ...

  2. JavaScript跨域资源请求(CORS)解决方案

    跨域:当协议.主域名.子域名.端口号中任意一个不相同时都不算同一个域,而在不同域之间请求数据即为跨域请求.解决方法有以下几种(如有错误欢迎指出)以请求图片url为例: 1.通过XMLHttpReque ...

  3. jsonp突破同源策略,实现跨域访问请求

    跨域访问问题,相信大家都有遇到过.这是一个很棘手的问题.不过道高一尺,魔高一丈,对于这类问题,总有解决问题的方案.最近我又接触到了这个问题,解决的途径是ajax+jsonp. 说到这个问题,不得不说一 ...

  4. 跨域资源请求(除jsonp以外)的方法

    ---------------------------------------------------------------------------------------------------- ...

  5. .net MVC下跨域Ajax请求(CORS)

    二.CROS (Cross-origin Resource Sharing) CROS相当于一种协议,由浏览器.服务端共同完成安全验证,进行安全的跨域资源共享.对于开发人员来说就跟在本站AJAX请求一 ...

  6. jsonp实现跨域资源访问

    平时项目中处理ajax跨域资源请求时,例如www.example2.com上的某个页面要请求www.example1.com的数据,我们使用得较多的是jsonp方式.jsonp通过JavaScript ...

  7. 跨域资源共享(CORS)在ASP.NET Web API中是如何实现的?

    在<通过扩展让ASP.NET Web API支持W3C的CORS规范>中,我们通过自定义的HttpMessageHandler自行为ASP.NET Web API实现了针对CORS的支持, ...

  8. JSON和JSONP有哪些区别,PhoneGap跨域请求如何实现

    前言 由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现. 当然了,通过调用强大的PhoneGap插件然后打包,你可以实现100%的Socke ...

  9. asp.net web api2.0 ajax跨域解决方案

    asp.net web api2.0 ajax跨域解决方案 Web Api的优缺点就不说了,直接说怎么跨域,我搜了一下,主要是有两种.  一,ASP.NET Web API支持JSONP,分两种 1, ...

随机推荐

  1. 图论中DFS与BFS的区别、用法、详解?

    DFS与BFS的区别.用法.详解? 写在最前的三点: 1.所谓图的遍历就是按照某种次序访问图的每一顶点一次仅且一次. 2.实现bfs和dfs都需要解决的一个问题就是如何存储图.一般有两种方法:邻接矩阵 ...

  2. 团队作业8——Beta 阶段冲刺1st day

    一.今日站立式会议照片 二.每个人的工作 (1) 昨天已完成的工作: 今天是冲刺的第一天,昨天完成的是团队成员任务的分配 (2) 今天计划完成的工作: 界面的完善 (3) 工作中遇到的困难: 对于界面 ...

  3. 201521123063 《Java程序设计》 第8周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 这次就不弄思维导图了,就直接总结了 遍历Map的方法 (1)使用键值对for循环 Map<String, ...

  4. 201521123026 《Java程序设计》第一周学习总结

    1. 本章学习总结 1.简要了解JAVA的发展史以及其特点(面向对象.跨平台性,健壮性,安全性,可移植性,多线程性,动态性等) 2.认识JAVA三大平台(Java SE,Java EE,JavaME) ...

  5. 201521123115《java程序设计》第9周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己以前 ...

  6. animation实现动画效果

    CSS3 animation 属性 CSS 参考手册 实例 使用简写属性,将动画与 div 元素绑定: div { animation:mymove 5s infinite; -webkit-anim ...

  7. 网络配置之基本网络配置(cenos6)

    目录: 关于IP的管理 Linux网卡的卸载与装载 配置网络接口 网络IP配置文件路由管理 路由管理命令 配置动态路由(简介) route的配置文件netstat命令IP命令 ip link 查看网络 ...

  8. XML-为XML添加DTD-Schema方法

    以后都按照如下方式为XML添加dtd或者schema 1,一般从源码jar包里找dtd文件,拷贝到自己的本地目录中: 比如mybatis在如下目录中有dtd :~/ mybatis-3.2.2-sou ...

  9. JPA关系映射之one-to-one

    一对一关联有两种实现方式:一种是共享的主键关联,另一种是一对一的外键关联 1.共享的主键关联:让两个对象具有共同的主键值,以表明他们之间的一一对应关系. Person.java类 public cla ...

  10. Linux 的集中重启的方法

    linux中有下面几条命令可以实现重新启动,这些命令都需要root用户的权限: reboot shutdown -r now #立刻重启 shutdown -r #过10分钟自动重启 shutdown ...