现实生活中,有人在写程序时,也会遇到一些跨域的问题,主要都是域名上,协议上,端口上的不同,所以才会阻止你访问。
通过JavaScript请求服务器时,受同源策略限制
同源:
- 协议相同
反过来协议不相同,就不属于同源策略
- 端口号相同
反过来,端口不相同,就不属于同源,例如:
- 域名相同
反过来域名不相同就不属于同源策略,例如:
m.baidu.com 无法访问:baidu.com
baidu.com 无法访问:souhu.com
现在我们的代码(JavaScript、php)在同一台服务器下,访问的时候,没有跨域,但是实际开发的时候,通常请求的数据不一定在当前的服务器下面,例如:手机端的项目放在一台服务器下:m.itbull.cn,PC端的项目保存到itbull.cn。
我设计两个虚拟主机:www.souhu.d和www.taobao.d,两个虚拟主机我都分别添加两个文件:index.html和data.php,
代码如下:
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="common.js"></script>
<script type="text/javascript">
$$.request({
method:"POST",
url:"http://www.taobao.d/data.php",
data:"",
dataType:"json",
success:function (result) {
console.log(result);
}
})
</script>
</head>
<body>
welcome to souhu
</body>
</html>
data.php
header('Content-Type:text/html,charset=utf-8');
$data['goods_name'] = '航空母舰';
$data['price'] = 198;
$data['nu'] = 10;
echo json_encode($data);
当我想利用前者去获取后者的数据的时候,程序便产生这样错误:
这样就防止你跨域访问其它域名下的数据。
跨域请求的解决之道:
(1)可以在PHP文件中,设置头信息,允许某些域名访问
header("Access-Control-Allow-Origin:*");
*表示所有的域名
如果感觉这样不安全的话,还可以单独指定哪些域名可以访问:
将*号设置为单独的域名即可,例如:只允许souhu域名访问:
header("Access-Control-Allow-Origin:http://www.souhu.com");
代码如下:
//header("Access-Control-Allow-Origin:*");
header("Access-Control-Allow-Origin:http://www.souhu.com");
header('Content-Type:text/html,charset=utf-8');
$data['goods_name'] = '航空母舰';
$data['price'] = 198;
$data['nu'] = 10;
echo json_encode($data);
(2)如果服务器端就是不通过header头信息实现的话,我们还有另外的方案:
通过JavaScript跨域请求实现:
原理借助:<img> <script>标签不受跨域限制的原理的实现
<img src=”1.jpg”>
<img src=”home/user/makeCaptcha”> 请求服务器makeCaptcha资源
通过加载外部文件的两种方式:
<script src=”common.js”>加载服务器的js文件
<script src=”data.php”>让data.php返回js代码、数据
第一种:
data.js代码如下:
amao({
name:"阿喵"
});
第二种通过请求PHP文件方法:为了使sccript标签更加灵活:
php代码如下:
echo $_GET['cb'].'({name:"毛啊1"})';
以上是解决跨域的一些方法,哈哈!!!!
common.js代码如下,自己之前学习ajax时学着封装的:
//封装ajax操作
var $$= {
request:function ( options ) {
//兼容各个浏览器的xmlHttpRequest对象
var xhr;
try{
//尝试执行
xhr = new XMLHttpRequest();
}catch (e){
//尝试使用IE6
try{
xhr = new ActiveXObject("Msxml2.XMLHTTP");
}catch(e){
//尝试使用IE5.5
try {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}catch(e){
alert('你的浏览器太破了,不值得拥有,去百度下载一个吧');
location.href = "http://www.baidu.com";
}
}
}
//判断提交的方式
if ( options.method == 'GET' ) {
//url地址传递中文,特殊字符符号
var content = encodeURIComponent(options.data);
//缓存怎么解决
var url = options.url+'?'+Math.random()+'&'+content;
xhr.open(options.method,url,true);
xhr.send();
} else if (options.method == 'POST') {
xhr.open(options.method,options.url,true);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send(options.data);
}
//监视xhr请求的状态,以及服务器的状态
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200 ) {
if (options.dataType == 'text') {
var result = xhr.responseText;
} else if(options.dataType == 'xml') {
var result = xhr.responseXML;
} else if (options.dataType == 'json') {
eval('var result='+xhr.responseText);
}
//拿到数据后怎么处理
options.success(result);
}
}
}
};
推荐文章:css字体跨域 php容联云通讯,发送短信、 微信H5支付