第五章*****************************************************************************************
AJAX处理数据格式application/javascript
问题: 一般.js文件中,script请求(任何人)(任何时间)js内容都一样
解决: 在服务器端返回"动态js",根据客户端不同或访问时间不同,js也不同
服务器端:
header("Content-Type:application/javascript;charset=utf-8");
echo "var msg = '你好';alert(msg);"; //msg随情景不同发生改变
客户端:
eval(xhr.responseText); //执行php中写的js程序
_______________________________________________________________________________________________
跨域访问(Cross Domain Request)
浏览器的同源策略,出于防范跨站脚本的攻击,禁止客户端脚本(如JavaScript)对不同域(协议、子域名、主域名protocal、端口port、主机host)的服务进行跨站调用
跨域定义:
① 两个域名不同 a.com → b.com
② 协议名不同 http://... → https://...
③ 主机名/IP不同 http://127.0.0.1/1.php → http://localhost/2.php
④ 端口号不同 http://127.0.0.1:80/1.php → http://127.0.0.1:8080/2.php
⑤ 子域名不同 1.a.com → 2.a.com
浏览器允许跨域请求的情形: img src="..." / link href="..." / script src="..." / iframe
浏览器默认禁止XHR(ajax)跨域访问(同级目录下除外)———可能会导致外来的数据对当前程序影响,造成数据安全风险
注意: 跨域并不是请求发不出去,而是请求能发出去,服务端能收到请求并正常返回结果,但结果被浏览器拦截了
三种行为会受到跨域限制:
① cookie、localStorage、indexDB
当一级域名相同,二级域名不同时,可设置相同的document.domain共享cookie
② DOM无法获得
③ ajax请求无法获得
方式一 JSONP
解决方案: JSONP JSON with Padding(填充式JSON)是一种使用JSON数据的方法,用于解决浏览器xhr跨域请求限制
jsonp思路:
发起异步请求时不使用'ajax对象xhr',而是使用一个动态创建的 script 标签代替xhr:
<script async src="跨域访问x.php"></script> //async:异步
步骤:
① 客户端:
方法1: 创建标签→设置属性→追加在head中
btn.onclick = function(){
var script=document.createElement("script");
script.src="http://127.0.0.1/kuayu/async.php";
script.async=true; //异步请求属性
document.head.appendChild(script); //创建一个script标签,并追加到head中
}
或者:
<script>
function doResponse(data){
console.log(jsondata); //处理获得的json数据
}
</script>
<script src="http://127.0.0.1:8090?doResponse=?"></script>
方法2: 使用dataType:"jsonp"//jsonp只能是 'GET' 形式,不要写POST,可能会报错
jQuery封装好的方法1,会在head开头插入script标签,响应成功后移除
$.ajax({
url:'http://127.0.0.1/web1703/day08/06_jsonp.php',
dataType:"jsonp",//使用JSONP形式调用函数,标志跨域请求
jsonp:'jsonp_callback',//跨域函数名的键值(服务器提取函数名的钥匙,默认为callback)
jsonpCallback:'doRespons',//客户端与服务端约定的函数名,取代jQuery自动生成的随机函数名
//若服务器已设置jsonp属性,则不需要再设置此属性(此值用来替代GET或POST请求中URL参数里的"callback=?"部分,并传给服务器)
success:function(res){}, //若设置jsonpCallback属性,则执行success函数,不执行error函数
//否则相反
error:function(err){}
});
② 创建函数,接收参数(设置jsonpCallback后可省略)
function doResponse(res){ //创建函数,用来接收服务器响应数据data
console.log(res);
}
③ 服务器:
<?php
header("Content-Type:application/javascript;charset=utf-8"); //向客户端发送js程序
$json='{"ename":"tom"}';
echo 'doResponse('.$json.');'; //拼接json字符串,js函数收到的参数就是这个json字符串
?> //客户端接收:doResponse(json),会执行这个函数
node中
res.end("callback("+str+")"); //发送的函数名要与ajax的jsonpCallback的值一致
//这个函数callback可不写,会自动接着执行ajax的success函数
jQuery中的jsonp类型,会创建一个查询字符串参数callback=?,这个参数会加在请求的URL后面,服务器端应当在JSON数据前加上回调函数名,以便完成一个有效的JSONP请求
如果要指定回调函数的参数名来取代默认的callback,可以通过设置$.ajax()的jsonp参数
当从服务器接收到数据时,实际上是用了<script>标签而不是XMLHttpRequest对象,$.ajax()不再返回一个XMLHttpRequest对象,并且也不会传递事件处理函数,比如beforeSend
方式二 CORS
jsonp只能是get形式,承载的信息量有限,所以信息量较大时CORS是不二选择
方法:
后台直接开启同源策略的访问限制,在允许被跨域访问的文件头部加上:
header("Access-Control-Allow-Origin:*");
或者:header("Access-Control-Allow-Origin:http://localhost:63342端口号");
可限制请求方式: header("Access-Control-Allow-Methods:POST,GET");
CORS需要浏览器和服务器同时支持。目前IE浏览器中IE10及以上才可正常发送请求,其它浏览器都支持
CORS是W3C中一项较新的方案,所以部分浏览器还没有对其进行支持或者完美支持
CORS在移动终端支持的不错,可以考虑在移动端全面尝试;PC上有不兼容和没有完美支持,所以小心踩坑
浏览器将CORS请求分成两类: 简单请求(simple request)和非简单请求(not-so-simple request)
只要同时满足以下两大条件,就属于简单请求:
① 请求方法是这三种方法之一: HEAD、GET、POST
② HTTP的头信息不超出这几种字段: Accept、Accept-Language、Content-Language、Last-Event-ID
Content-Type只限于三个值: application/x-www-form-urlencoded
multipart/form-data text/plain
凡是不同时满足上面两个条件,就属于非简单请求
对于简单请求,浏览器直接发出CORS请求。就是在头信息之中,增加一个Origin字段
非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json
CORS定义一种跨域访问的机制,可以让AJAX实现跨域访问。CORS 允许一个域上的网络应用向另一个域提交跨域 Ajax 请求。实现此功能只需由服务器发送一个响应标头即可
① 客户端 (与正常请求一致):
btn.onclick = function(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function (){
if (xhr.readyState === 4 & xhr.status === 200){
var obj=JSON.parse(xhr.responseText); //将后台相应的数据转换成对象
console.log(obj);
}
}
xhr.open("GET", "http://127.0.0.1/z_review/jsonp/cors.php", true);
xhr.send(null);
}
② 服务器端:
<?php
header("Access-Control-Allow-Origin:*"); //比正常响应多一个此字段
header("Access-Control-Allow-Origin: http://localhost:63342"); //或者只允许特定网址访问
header("Content-Type:application/json;charset=utf-8"); //若不加此段会返回字符串
//加上之后会返回一个对象
$json='{"ename":"tom"}';
echo $json;
?>
Node.js中使用CORS跨域:
①服务器端:
app.all("*",function(req,res,next){
res.header("Access-Control-Allow-Origin:*"); //添加此字段
res.header("Access-Control-Allow-Origin","http://localhost:63342"); //只允许特定网址访问
next();
})
app.get("/kuayu",(req,res)=>{
console.log(req);
res.json({ename:"tom"});
})
② 客户端比同域请求的url多出ip及端口:
btn.onclick = function(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function (){
if (xhr.readyState === 4 & xhr.status === 200){
var obj=JSON.parse(xhr.responseText); //将后台相应的数据转换成对象
console.log(obj);
}
}
xhr.open("GET", "http://127.0.0.1:8080/kuayu", true); //必须加http
xhr.send(null);
}
方式三、通过修改document.domain来跨子域
方式四、使用window.name来进行跨域
方式五、使用HTML5中新引进的window.postMessage方法来跨域传送数据(IE 6/7 不支持)
方式六、nginx反向代理
方式七、使用WebSocket
第六章*****************************************************************************************
XML(java 旧项目)
html: 超文本标记语言,所有标签预定义好: h1、h2用于描述一个网页结构
xml: 可扩展的标签语言,所有标签都是自定义的,用于描述一段数据,尤其是复合数据
xml语法: XML和HTML用途不同,xml语法更加严格
① xml文档类型声明
<?xml version="1.0" encoding="utf-8"?>
② 整遍xml有且只有一个根元素,比如: <books></books>
③ 标签有开始必须有结束,开始标签与结束的标签完全相同: <book></book>
④ 标签可以嵌套不能交叉: <book><id><i></i></id></book>是正确的
⑤ 标签可以有任意属性
服务器端: 通过程序xml文档并且发送
<?php
header("Content-Type:application/xml;charset=utf-8");
echo "<?xml version='1.0' encoding='utf-8'?>";
echo "<根元素>"; //在php中输出时,必须用单引号或双引号括起来
echo "<name>......</name>";
echo "</根元素>";
?>
客户端:
使用DOM操作原生AJAX发送请求xml数据
btn1.onclick=function(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange=function(){
if(xhr.readyState===4&&xhr.status===200){
var doc=xhr.responseXML;
}
}
xhr.open('get','xml.php',true);
xhr.send(null);
}
使用jQuery操作AJAX发送请求数据
btn2.onclick=function(){
$.ajax({
type:"get",
url:"xml.php",
dataType:"xml", //指定服务器返回类型
success:function(data){...}
});
}
处理XML数据的方法:
① data.documentElement.getElementsByTagName("row") //使用原生DOM访问XML数据
② $(data).find("row") //使用jQuery访问XML数据
可以使用操作DOM的方式访问XML的标签、属性、值
$(res).find("p").each(function(){ console.log($(this).attr('id')) })
第七章*****************************************************************************************
Cookie
作用: 保存(指定保存时间)用户添加的数据,默认情况会话结束数据就删除了(一般是服务器使用)
会话: 是一个操作过程,当用户打开浏览器请求指定页面(会话开始),进行操作,最后关闭浏览器(会话结束)
特点:
① 可以自动在浏览器端和服务器端来回传递,存储量约4k,所以不要将不必要的数据放到Cookie中
② 可以设置过期时间,超出时间后,自动消失
操作方式
① 保存数据至cookie(保存cookie的页面):
document.cookie='uid='+uid;
document.cookie="uname="+uname; //不会覆盖除uname的值
② 从cookie中获取数据(调用cookie的页面):
var cookieArray=document.cookie.split("; ");
var cookieObj={};
for(var i=0;i<cookieArray.length;i++){
var sub=cookieArray[i].split("=");
var key=sub[0];
var val=sub[1];
cookieObj[key]=val;
}
if(!cookieObj.uid){
location.href="输入cookie内容的页面";
}
修改cookie过期时间
var now = new Date();
now.setFullYear(now.getFullYear()+1);
设置为一年后过期:
document.cookie = 'answer='+JSON.stringify(cookieObj.answer)+'; expires='+now.toGMTString();
设置为永远不过期:
document.cookie = 'answer='+JSON.stringify(cookieObj.answer)+'; expires=Fri, 31 Dec 9999 23:59:59 GMT';
设置cookie路径: document.cookie = "name=value; path=/";
注意事项: cookie数据保存在客户端浏览器中,不要将安全性高数据保存在cookie
cookie保存数据通常是: 用户编号/用户喜欢产品编号/昵称
XSS(跨站脚本攻击)是指攻击者在返回的HTML中嵌入javascript脚本,为了减轻这些攻击,需要在HTTP头部配上set-cookie:
httponly 这个属性可以防止XSS,它会禁止javascript脚本来访问cookie
secure 这个属性告诉浏览器仅在请求为https的时候发送cookie