Ajax学习

原生AJAX

Ajax主要使用【XmlHttpRequest】对象来完成请求的操作

1、XmlHttpRequest对象介绍

主要方法:

void open(String method,String url,Boolen async) //用于创建请求
参数:
	method:请求的方式(字符串类型),如:POST、GET、DELETE...
    url:   要请求的地址(字符串类型)
    async   是否异步(布尔类型)
    
void send(String body) //用于发送请求
参数:
	body:要发送的数据(字符串类型)
    
void setRequestHeader(String header,String value)
    用于设置请求头
 
    参数:
        header: 请求头的key(字符串类型)
        vlaue:  请求头的value(字符串类型)

String getAllResponseHeaders()
    获取所有响应头
 
    返回值:
        响应头数据(字符串类型)
        
String getResponseHeader(String header)
    获取响应头中指定header的值
 
    参数:
        header: 响应头的key(字符串类型)
 
    返回值:
        响应头中指定的header对应的值
void abort()
 
    终止请求

XmlHttpRequest对象的主要属性:

a. Number readyState
   状态值(整数)
 
   详细:
      0-未初始化,尚未调用open()方法;
      1-启动,调用了open()方法,未调用send()方法;
      2-发送,已经调用了send()方法,未接收到响应;
      3-接收,已经接收到部分响应数据;
      4-完成,已经接收到全部响应数据;
 
b. Function onreadystatechange
   当readyState的值改变时自动触发执行其对应的函数(回调函数)
 
c. String responseText
   服务器返回的数据(字符串类型)
 
d. XmlDocument responseXML
   服务器返回的数据(Xml对象)
 
e. Number states
   状态码(整数),如:200、404...
 
f. String statesText
   状态文本(字符串),如:OK、NotFound...

例子:

//index.html
<div>
    <a class='btn' onclick='AjaxSubmit2();'>点我</a>
</div>

<script>
    function AjaxSubmit2(){
        var xhr= new XMLHttpRequest();
        xhr.onreadystatechange =function(){
            if(xhr.readyState == 4){
                //接收完毕服务器返回的数据
                console.log(xhr.responseText);
            }
        };
        xhr.open('GET','/ajax.html?p=123');//get请求时
        xhr.send(null);

        xhr.open('POST','/ajax.html');//post请求时,需要发送请求头,
        xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset-UTF-8') //一般是固定写法
        xhr.send("p=456")
    }
</script>

### iframe上传文件

iframe 元素会创建包含另外一个文档的内联框架(即行内框架)。下面将会利用iframe实现上传文件的功能:

#views.py
def upload(request):
    return render(request,'upload.html')

def upload_img(request):
    import os,uuid #uuid模块用于生成全局标识符
    nid =str(uuid.uuid4())
    ret={'status':True,'data':None,'message':None}
    obj=request.FIFES.get('k3')
    
    file_path=os.path.join('static',nid+obj.name)
    f=open(file_path,'wb')
    for line in obj.chunks():#读取上传的数据
        f.write(line)
    f.close()
    ret['data']=file_path
    return HTtpResponse(json.dumps(ret))
        
<iframe style='...' id="iframe1" name="ifra1"></iframe>
<form id="fm1" action="upload_img.html" method="post" enctype="multipartform-data" target="ifra1">
    <input type="file" name='k3' onchange="uploadFile();"/>
</form>
    <div id="preview"></div>
    
    <script>
        function uploadFile(){
            document.getElmentBuId('iframe1').onload=reloadIframe1;
            document.getElmentBuId('fm1').submit();
        }
        function reloadIframe1(){
            var content=this.contentWindow.document.body.innerHTML;
            var obj=JSON.parsr(content);
            var tag=document.createElement('img');
            tag.src=obj.data  //将src指向文件路径
            $('#preview').empty().append(tag)
        }
    </script>
    
</form>

跨域Ajax

跨域,指跨域名访问,如http://www.c1.com 域名向 http://www.c2.com域名发送请求

由于浏览器存在同源策略基址,同源策略机制阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性。而由于同源策略是浏览器的限制,所以请求的发送和响应可以进行,只是浏览器不允许

浏览器同源策略并不是对所有的请求都制约:

  • 制约:XmlHttpRequest
  • 不制约:img、iframe、script等具有src属性的标签

1、JSONP实现跨域请求

JSONP(JSONP - JSON with Padding是JSON的一种“使用模式”),利用script标签的src属性(浏览器允许script标签跨域)

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <p>
        <input type="button" onclick="Jsonp1();"  value='提交'/>
    </p>

    <p>
        <input type="button" onclick="Jsonp2();" value='提交'/>
    </p>

    <script type="text/javascript" src="jquery-1.12.4.js"></script>
    <script>
        function Jsonp1(){
            var tag = document.createElement('script');
            tag.src = "http://c2.com:8000/test/";
            document.head.appendChild(tag);
            document.head.removeChild(tag);

        }

        function Jsonp2(){
            $.ajax({
                url: "http://c2.com:8000/test/",
                type: 'GET',
                dataType: 'JSONP',
                success: function(data, statusText, xmlHttpRequest){
                    console.log(data);
                }
            })
        }


    </script>
</body>
</html>

2、CORS

随着技术的发展,现在的浏览器可以支持主动设置从而允许跨域请求,即:跨域资源共享(CORS,Cross-Origin Resource Sharing),其本质是设置响应头,使得浏览器允许跨域请求

条件:
    1、请求方式:HEAD、GET、POST
    2、请求头信息:
        Accept
        Accept-Language
        Content-Language
        Last-Event-ID
        Content-Type 对应的值是以下三个中的任意一个
                                application/x-www-form-urlencoded
                                multipart/form-data
                                text/plain
 
注意:同时满足以上两个条件时,则是简单请求,否则为复杂请求

简单请求与非简单请求的区别:

  • 简单请求:一次请求
  • 非简单请求:两次请求,在发送数据前会先发一次请求用于做“预检”,只有“预检”通过后才再发送一次请求用于数据传输

关于预检

- 请求方式:OPTIONS
- “预检”其实做检查,检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息
- 如何“预检”
     => 如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过
        Access-Control-Request-Method
     => 如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过
        Access-Control-Request-Headers

基于cors实现Ajax请求:

a、支持跨域,简单请求

​ 服务器设置响应头:Access-Control-Allow-Origin = '域名' 或 '*'

b、支持跨域,复杂请求

​ 由于复杂请求时,首先会发送“预检”请求,如果“预检”成功,则发送真实数据。

  • “预检”请求时,允许请求方式则需服务器设置响应头:Access-Control-Request-Method
  • “预检”请求时,允许请求头则需服务器设置响应头:Access-Control-Request-Headers
  • “预检”缓存时间,服务器设置响应头:Access-Control-Max-Age
posted @ 2019-05-20 21:04  Dandelion-L  阅读(83)  评论(0)    收藏  举报