AJAX跨域请求与AJAX浏览器缓存处理

AJAX

原生post 提交

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script type="text/javascript">
window.onload=function(){
document.getElementById('username').onblur=function(){
var username=document.getElementById('username').value;
username=encodeURIComponent(username); //字符编码,防止与URL关键字相混淆
var req=new XMLHttpRequest();
req.open('post','./5-demo.php'); //创建连接
req.onreadystatechange=function(){ //当状态发生变化
if(req.readyState==4 && req.status==200){
var result=req.responseText; //接受返回的信息
alert(result);
}
}
req.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); //设置请求头
req.send('username='+username); //post提交数据
}
}
</script>
<input type="text" name="" id="username">

解决浏览器缓存

  1. 方法一:添加一个随机数,使得URL地址变得唯一
    req.open('open','./1.php?'+Math.random());
  2. 方法二:告知浏览器不要缓存页面
    header("Cache-Control:no-cache");
    header("Pragma:no-cache");
  3. 方法三:当浏览器接受到相应的时候,缓存就已经过期
    header("Expires:-1");
  4. 方法四:
    设置请求头:req.setRequestHeader('If-Modified-Since','0');
    客户端通过If-Modified-Since头将服务器端最后发过来的页面时间戳发送回去,服务器端通过时间戳判断客户端的页面是否是最新的,如果不是最新的则返回新的内容,如果是最新的,则返回304重定向到客户端缓存中的页面。

跨域请求

背景:浏览器为了安全考虑,不允许跨域请求。
同源策略:一个域名下的JS只能请求同一个域名下的文件,不能跨域请求
解决方法:

  1. HTML标记的src属性没有同源限制
    <script src="http://www.uiste.com/test.js"></script>

  2. PHP同域代理

    1
    2
    文件一:<?php echo file_get_contents('http://www.uiste.com/test.php'); ?>
    文件二:<script>req.open('open','6-demo.php')</script>
  3. 设置响应头

    1
    2
    3
    4
    header("Access-Control-Allow-Origin: http://a.com"); // 允许a.com发起的跨域请求  
    //如果需要设置允许所有域名发起的跨域请求,可以使用通配符 *
    header("Access-Control-Allow-Origin: *"); // 允许任意域名发起的跨域请求
    header('Access-Control-Allow-Headers: X-Requested-With,X_Requested_With');
  4. jsonp
    JSONP是客户端用get的方式传递一个回调函数的名字给服务器,服务器返回拼接好的调用函数字符串给客户端,然后客户端用js生成script标记,用script标记的src属性引入服务器生成的js代码,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    PHP文件一:
    $stu = array('tom','berry');
    $stu = json_encode($stu);
    $fn = $_GET['fn'];
    echo "$fn($stu)";
    HTML文件二:
    <script type="text/javascript">
    function show(msg){alert(msg);}
    window.onload=function(){
    document.getElementById('btn').onclick=function(){
    var script=document.createElement('script');
    script.src="http://www.uiste.com/test.php?fn=show";
    var body=document.getElementByTagName('body')[0];
    body.appendChild(script);
    }
    }
    </script>
    <input type="button" value="点击" id="btn">

jsonp案例

实例1
test.html

1
2
3
4
5
6
7
8
9
10
11
12
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
<script src="jquery-1.5.2.min.js"></script>
<script src="ajax.js"></script>
</head>

<body>
</body>
</html>

ajax.js

1
2
3
4
5
6
7
8
9
10
11
12
13
$.ajax({
type : "post",
url : "ajax.php",
dataType : "jsonp",
jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(默认为:callback)
jsonpCallback:"success_jsonpCallback",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名
success : function(json){
alert('success');
},
error:function(){
alert('fail');
}
});

ajax.php

1
2
3
4
5
6
7
<?php

$data = ".......";
$callback = $_GET['callback'];
echo $callback.'('.json_encode($data).')';
exit;
?>

jquery-1.5.2.min.js
当使用jsonp时,使用 JSONP 形式调用函数时,如 “myurl?callback=?” jQuery 将自动替换 ? 为正确的函数名,以执行回调函数。

实例2
test.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
<script src="jquery-1.5.2.min.js"></script>
<script src="ajax.js"></script>
</head>

<body>
<form name="form">
<input type="text" name="sex">
<input type="text" name="age">
<input type="button" id="btn" value="button" />
</form>
</body>
</html>

ajax.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$(document).ready(function(){

$("#btn").click(function(k) {
//...
var j = $("form").serializeArray();//序列化name/value
$.ajax({
type: 'GET', //这里用GET
url: 'ajax.php',
dataType: 'jsonp', //类型
data: j,
jsonp: 'callback', //jsonp回调参数,必需
async: false,
success: function(result) {//返回的json数据
alert(result.message); //回调输出

result = result || {};
if (result.msg=='err'){
alert(result.info);
}else if (result.msg=="ok"){
alert('提交成功');
}else{
alert('提交失败');
}

},
timeout: 3000
})
//...
});

});

ajax.php

1
2
3
4
5
6
7
8
<?php
$callback = isset($_GET['callback']) ? trim($_GET['callback']) : ''; //jsonp回调参数,必需
$date = array("age"=>$_GET['age'], "message"=>$_GET['age']);
$date["msg"]="err";
$date["info"]="因人品问题,发送失败";
$tmp= json_encode($date); //json 数据
echo $callback . '(' . $tmp .')'; //返回格式,必需
?>