ajax大全

一、ajax介绍

用户通过浏览器向浏览器提交数据:

1、  通过form表单发送  (页面需要刷新)

2、  通过Ajax发送  (页面无刷新)

 

Ajax  Asynchronous Javascript and XML (异步的Javascript和XML现在都不这样用了现在用json)一种创建交互式网页应用的网页开发技术方案;现在都用Asynchronous Javascript and JSON

通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。传统的网页(不使用 AJAX)如果需要更新内容,必须重载整个网页页面。

二、iframe伪造Ajax

“伪”Ajax

由于HTML标签的frame标签具有局部加载内容的特性,所以可以使用其来伪造Ajax请求

通过iframe的src可以跳转到任何网站的特性来伪造局部加载Ajax

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        input.aa{
            cursor: pointer;
        }
    </style>
</head>
<body>
    <div>
        <p>请输入要加载的地址:<span id="currentTime"></span></p>
        <p>
            <input id="url" type="text"/>
            <input class="aa" type="button" value="刷新" onclick="LoadPage();"/>
        </p>
    </div>
    <div>
        <h3>加载页面的位置:</h3>
        <iframe id="iframePosition" style="width: 100%;height: 500px;"></iframe>
    </div>
    <script type="text/javascript">
        //页面全部加载之后自动执行后面的函数
        window.onload= function () {
            var myDate=new Date();
            document.getElementById("currentTime").innerText=myDate.getTime()
        };

        function LoadPage(){
        //用户输入什么然后触发iframe的src功能
            var targetUrl=document.getElementById("url").value;
            document.getElementById("iframePosition").src=targetUrl;
        }
    </script>
</body>
</html>
html代码

三、原生Ajax

Ajax主要就是使用XMLHttpRequest对象来完成请求的操作,该对象在主流浏览器中均存在(除了早期的IE),Ajax首次出现在IE5.5中存在(Active控件)

1、XmlHttpRequest对象介绍

a. void open(String method,String url,Boolen async)
   用于创建请求
   参数:
       method: 请求方式(字符串类型),如:POST、GET、DELETE...
       url:    要请求的地址(字符串类型)
       async:  是否异步(布尔类型)
  
b. void send(String body)
    用于发送请求
    参数:
        body: 要发送的数据(字符串类型)
  
c. void setRequestHeader(String header,String value)
    用于设置请求头
    参数:
        header: 请求头的key(字符串类型)
        vlaue:  请求头的value(字符串类型)
  
d. String getAllResponseHeaders()
    获取所有响应头
    返回值:
        响应头数据(字符串类型)
  
e. String getResponseHeader(String header)
    获取响应头中指定header的值
    参数:
        header: 响应头的key(字符串类型)
    返回值:
        响应头中指定的header对应的值
  
f. 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
   状态码(整数),如:200404...
  
f. String statesText
   状态文本(字符串),如:OK、NotFound...
XmlHttpRequest对象的主要属性:

2、跨浏览器支持

    • XmlHttpRequest
      IE7+, Firefox, Chrome, Opera, etc.
    • ActiveXObject("Microsoft.XMLHTTP")
      IE6, IE5

 

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

    <h1>XMLHttpRequest - Ajax请求</h1>
    <input type="button" onclick="XhrGetRequest();" value="Get发送请求" />
    <input type="button" onclick="XhrPostRequest();" value="Post发送请求" />

    <script src="/statics/jquery.js"></script>
    <script type="text/javascript">

        function GetXHR(){
            var xhr = null;
            if(XMLHttpRequest){
                xhr = new XMLHttpRequest();
            }else{
                xhr = new ActiveXObject("Microsoft.XMLHTTP");
            }
            return xhr;

        }

        function XhrPostRequest(){
            var xhr = GetXHR();
            // 定义回调函数
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4){
                    // 已经接收到全部响应数据,执行以下操作
                    var data = xhr.responseText;
                    console.log(data);
                }
            };
            // 指定连接方式和地址----文件方式
            xhr.open('POST', "/s1", true);
            // 设置请求头
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
            // 发送请求
            xhr.send('n1=1;n2=2;');
        }

        function XhrGetRequest(){
            var xhr = GetXHR();
            // 定义回调函数
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4){
                    // 已经接收到全部响应数据,执行以下操作
                    var data = xhr.responseText;
                    console.log(data);
                }
            };
            // 指定连接方式和地址----文件方式
            xhr.open('get', "/s1", true);
            // 发送请求
            xhr.send();
        }

    </script>

</body>
</html>
基于原生AJAX - Demo
#/usr/bin/env python
#-*- coding:utf-8-*-
import tornado.ioloop
import tornado.web
class IndexHandler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        self.render("s1.html")
settings={
    "template_path":"views",
    "static_path":"statics",
    "static_url_prefix":"/statics/"
}
application = tornado.web.Application([
    (r"/s1",IndexHandler),
],**settings)
if __name__=="__main__":
    application.listen(7777)
    tornado.ioloop.IOLoop.instance().start()
python代码

 

四、jquery发送Ajax请求

jQuery 既然是JavaScript的类库,那肯定也封装了AJAX使用相关方法,会使我们开发用起来更简单。

jQuery Ajax的本质无疑是 XMLHttpRequest 或 ActiveXObject 

注:2.+的版本不再支持IE9以下的浏览器

 jQuery Ajax 常用方法有三个:get、post、ajax:

# jQuery Ajax 常用方法列表
 
jQuery.get(...)
    所有参数:
         url: 待载入页面的URL地址
        data: 待发送 Key/value 参数。
     success: 载入成功时回调函数。
    dataType: 返回内容格式,xml, json,  script, text, html
 
jQuery.post(...)
    所有参数:
         url: 待载入页面的URL地址
        data: 待发送 Key/value 参数
     success: 载入成功时回调函数
    dataType: 返回内容格式,xml, json,  script, text, html
 
jQuery.ajax(...)
    部分参数:
            url:请求地址
           type:请求方式,GET、POST(1.9.0之后用method)
        headers:请求头
           data:要发送的数据
    contentType:即将发送信息至服务器的内容编码类型(默认: "application/x-www-form-urlencoded; charset=UTF-8")
          async:是否异步
        timeout:设置请求超时时间(毫秒)
 
     beforeSend:发送请求前执行的函数(全局)
       complete:完成之后执行的回调函数(全局)
        success:成功之后执行的回调函数(全局)
          error:失败之后执行的回调函数(全局)
 
        accepts:通过请求头发送给服务器,告诉服务器当前客户端课接受的数据类型
       dataType:将服务器端返回的数据转换成指定类型
                   "xml": 将服务器端返回的内容转换成xml格式
                  "text": 将服务器端返回的内容转换成普通文本格式
                  "html": 将服务器端返回的内容转换成普通文本格式,在插入DOM时,如果包含js标签,会尝试去执行
                "script": 尝试将返回值当作JavaScript去执行,然后再将服务器端返回的内容转换成普通文本格式
                  "json": 将服务器端返回的内容转换成相应的JavaScript对象
                 "jsonp": JSONP 格式
使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数,如果不指定,jQuery 将自动根据HTTP包MIME信息返回相应类型(an XML MIME type will yield XML, in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything else will be returned as a string
 
     converters: 转换器,将服务器端的内容根据指定的dataType转换类型,并传值给success回调函数
# jQuery Ajax 方法列表

jQuery.get(...)
    所有参数:
         url: 待载入页面的URL地址
        data: 待发送 Key/value 参数。
     success: 载入成功时回调函数。
    dataType: 返回内容格式,xml, json,  script, text, html

jQuery.post(...)
    所有参数:
         url: 待载入页面的URL地址
        data: 待发送 Key/value 参数
     success: 载入成功时回调函数
    dataType: 返回内容格式,xml, json,  script, text, html

jQuery.getJSON(...)
    所有参数:
         url: 待载入页面的URL地址
        data: 待发送 Key/value 参数。
     success: 载入成功时回调函数。


jQuery.getScript(...)
    所有参数:
         url: 待载入页面的URL地址
        data: 待发送 Key/value 参数。
     success: 载入成功时回调函数。

jQuery.ajax(...)
    部分参数:
            url:请求地址
           type:请求方式,GET、POST(1.9.0之后用method)
        headers:请求头
           data:要发送的数据
    contentType:即将发送信息至服务器的内容编码类型(默认: "application/x-www-form-urlencoded; charset=UTF-8")
          async:是否异步
        timeout:设置请求超时时间(毫秒)

     beforeSend:发送请求前执行的函数(全局)
       complete:完成之后执行的回调函数(全局)
        success:成功之后执行的回调函数(全局)
          error:失败之后执行的回调函数(全局)


        accepts:通过请求头发送给服务器,告诉服务器当前客户端课接受的数据类型
       dataType:将服务器端返回的数据转换成指定类型
                   "xml": 将服务器端返回的内容转换成xml格式
                  "text": 将服务器端返回的内容转换成普通文本格式
                  "html": 将服务器端返回的内容转换成普通文本格式,在插入DOM中时,如果包含JavaScript标签,则会尝试去执行。
                "script": 尝试将返回值当作JavaScript去执行,然后再将服务器端返回的内容转换成普通文本格式
                  "json": 将服务器端返回的内容转换成相应的JavaScript对象
                 "jsonp": JSONP 格式
                          使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数
                  如果不指定,jQuery 将自动根据HTTP包MIME信息返回相应类型(an XML MIME type will yield XML, in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything else will be returned as a string

     converters: 转换器,将服务器端的内容根据指定的dataType转换类型,并传值给success回调函数
             $.ajax({
                  accepts: {
                    mycustomtype: 'application/x-some-custom-type'
                  },
                  // Expect a `mycustomtype` back from server
                  dataType: 'mycustomtype',
                  // Instructions for how to deserialize a `mycustomtype`
                  converters: {
                    'text mycustomtype': function(result) {
                      // Do Stuff
                      return newresult;
                    }
                  },
                });
jquery AJAX 方法列表
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <p>
        <input type="button" onclick="XmlSendRequest();" value='Ajax请求' />
    </p>


    <script type="text/javascript" src="jquery-1.12.4.js"></script>
    <script>

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


    </script>
</body>
</html>
基于jQueryAjax - Demo
1、    导入jquery
2、    导入$.get({
url:”地址”,
data:{“k1”:”v1”,...},
dataType:”script”,-->这里面可以有text,json,xml,script,jsonp.即这里是什么,那么da就默认是什么
success:function(da){
}
})
$.getJson()
$.getScript()
这两个方法就是上面缩写(内部会调用get方法),也就是把url,data,函数放到这里面,然后dataType()里面填写类型

3、    或者导入$.post({
url:”地址”,
data:{“k1”:”v1”,...},
dataType:”script”,-->这里面可以有text,json,xml,script,jsonp.即这里是什么,那么da就默认是什么
success:function(da){
}
)
总结

五、文件上传

一、文件上传之form

下面上传文件,并且把这个文件单独分到一个文件包里面,并且让让这个文件展示在前台上面,这个上传必须是文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    1、这里注意,在input中的checkbox中,必须要有value才可以,这样提交到
    后台,才会分得清到底用户点击了谁
    2、要上传文件在form表单中必须定义enctype="multipart/form-data"
    3、把上传的文件展示在前台页面上,可以自定义一个空列表。然后把上传的文件名传入
    并且结合模板语言,把内容传入到这个列表中并且展示在页面
</head>
<body>
    <ul>
        {% for item in img_list %}
        <li><img style="height: 100px;width: 100px" src="/statics/img/{{item}}"></li>
        {% end %}
    </ul>

<form action="index" method="post" enctype="multipart/form-data">
    <input type="text" name="user"/>
    <h3>爱好</h3>
    <input name="favor" type="checkbox" value="1"/>篮球;
    <input name="favor" type="checkbox" value="2"/>足球;
    <input name="favor" type="checkbox" value="3"/>玻璃球;

    定义上传文件
    <input type="file" name="fafafa"/>
    <input type="submit" value="提交"/>

</form>
</body>
</html>
html代码
 1 #/usr/bin/env python
 2 #-*- coding:utf-8-*-
 3 import tornado.ioloop
 4 import tornado.web
 5 
 6 IMG_LIST=[]
 7 class IndexHandler(tornado.web.RequestHandler):
 8     def get(self, *args, **kwargs):
 9         #给用户返回前端页面和这个列表,并且在前台把这个列表填充内容
10         self.render("index.html" ,img_list=IMG_LIST)
11     def post(self, *args, **kwargs):
12         # print(self.get_argument("user"))
13         # print(self.get_argument("favor"))
14         # print(self.get_argument("fafafa"))
15 
16         #获取文件名字
17         file_metas = self.request.files["fafafa"]
18         # print(file_metas)  下面是获取内容
19         for meta in file_metas:
20         #要上传的文件名
21             file_name = meta['filename']
22         #把文件上传到后台的目录中
23             import os
24             with open(os.path.join("statics","img",file_name),'wb') as up:
25                 up.write(meta['body'])
26             #把上传的文件名传入到这个列表中
27             IMG_LIST.append(file_name)
28 
29         self.render("1")
30 
31 settings={
32     "template_path":"views",
33     "static_path":"statics",
34     "static_url_prefix":"/statics/"
35 }
36 application = tornado.web.Application([
37     (r"/index",IndexHandler),
38 ],**settings)
39 if __name__=="__main__":
40     application.listen(7777)
41     tornado.ioloop.IOLoop.instance().start()
42 
43 
44 
45 
46 最主要是下面的方法:
47     def post(self, *args, **kwargs):
48         file_metas = self.request.files["fff"]
49         # print(file_metas)
50         for meta in file_metas:
51             file_name = meta['filename']
52             with open(file_name,'wb') as up:
53                 up.write(meta['body'])
python代码

二、文件上传之Ajax

基于原生Ajax上传代码

 1 <!DOCTYPE html>
 2 <html>
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <title></title>
 6 </head>
 7 <body>
 8     <input type="file" id="img" />
 9     <input type="button" onclick="UploadFile();" />
10     <script>
11         function UploadFile(){
12             //获取文件对象
13             var fileObj = document.getElementById("img").files[0];
14             //创建form对象
15             var form = new FormData();
16             form.append("user", "v1");
17             form.append("favor","1");
18             form.append("fafafa", fileObj);
19 
20             var xhr = new XMLHttpRequest();
21             xhr.open("post", '/index', true);
22             xhr.send(form);
23         }
24     </script>
25 </body>
26 </html>
前台html代码 Ajax方式
 1 #/usr/bin/env python
 2 #-*- coding:utf-8-*-
 3 import tornado.ioloop
 4 import tornado.web
 5 
 6 IMG_LIST=[]
 7 class IndexHandler(tornado.web.RequestHandler):
 8     def get(self, *args, **kwargs):
 9         #给用户返回前端页面和这个列表,并且在前台把这个列表填充内容
10         self.render("index.html" ,user_list=IMG_LIST)
11     def post(self, *args, **kwargs):
12         print(self.get_argument("user"))
13         print(self.get_argument("favor"))
14         # print(self.get_argument("fafafa"))
15 
16         #获取文件名字
17         file_metas = self.request.files["fafafa"]
18         # print(file_metas)  下面是获取内容
19         for meta in file_metas:
20         #要上传的文件名
21             file_name = meta['filename']
22         #把文件上传到后台的目录中
23             import os
24             with open(os.path.join("statics","img",file_name),'wb') as up:
25                 up.write(meta['body'])
26             #把上传的文件名传入到这个列表中
27             IMG_LIST.append(file_name)
28 
29         self.render("index.html")
30 
31 settings={
32     "template_path":"views",
33     "static_path":"statics",
34     "static_url_prefix":"/statics/"
35 }
36 application = tornado.web.Application([
37     (r"/index",IndexHandler),
38 ],**settings)
39 if __name__=="__main__":
40     application.listen(7777)
41     tornado.ioloop.IOLoop.instance().start()
后台python代码

三、基于jQuery和Ajax上传文件

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <input type="file" id="img" />
    <input type="button" onclick="UploadFile();" />
    <script src="/statics/jquery.js"></script>
    <script>
        function UploadFile(){
            var fileObj = $("#img")[0].files[0];
            var form = new FormData();
            form.append("user", "v1");
            form.append("favor", "v1");
            form.append("fafafa", fileObj);

            $.ajax({
                type:'POST',
                url: '/index',
                data: form,
                processData: false,  // tell jQuery not to process the data
                contentType: false,  // tell jQuery not to set contentType
                success: function(arg){
                    console.log(arg);
                }
            })
        }
    </script>
</body>
</html>
View Code

四、上传文件之Iframe

如果遇到浏览器不支持原生ajax或者jquery +ajax的形式上传文件,这个时候就可以选择用iframe来上传文件

这种形式的兼容性会更好一点,因为所有的浏览器都有iframe这个标签,利用iframe作为一个通道来来上传

 1 <!DOCTYPE html>
 2 <html>
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <title></title>
 6     <style>
 7         .hide{
 8             display: none;
 9         }
10     </style>
11 </head>
12 <body>
13     <form id="my_form" name="form" action="/index" method="POST"  enctype="multipart/form-data" >
14         <div id="main">
15             <input name="user"   type="text" />
16             <input name="favor"   type="text" />
17             <input name="fafafa" id="my_file"  type="file" />
18             <input type="button" name="action" value="Upload" onclick="redirect()"/>
19             <iframe id='my_iframe' name='my_iframe' src=""  class="hide"></iframe>
20         </div>
21     </form>
22     <script src="/statics/jquery.js"></script>
23     <script>
24         function redirect(){
25             document.getElementById('my_iframe').onload = Testt;
26             //my_form这个标签的目标提交到my_iframe,然后iframe加载完成之后执行上面的方法
27             document.getElementById('my_form').target = 'my_iframe';
28             document.getElementById('my_form').submit();
29 
30         }
31         
32         function Testt(ths){
33             //把iframe的内容提交给t
34             var t = $("#my_iframe").contents().find("body").text();
35             console.log(t);
36         }
37     </script>
38 </body>
39 </html>
View Code

六、跨域ajax

 

1、对于Ajax请求,如果跨域名请求,默认【浏览器】不允许

出错地方在于:

在本地的ajax请求自己的域名是可以进行的,但是本地的Ajax请求的不是自己的域名,而是其他的域名,那么别的服务器也会进行处理和返回请求,但是浏览器接收的过程中出错了。浏览器的同源策略导致的 所以默认的ajax跨域请求是不能够完成的

 

2、允许跨域的有:

<script块 src=http://xxx.com/>

<img src=http://js.com/>

<iframe src=””/>

不允许跨域:

ajax

 

 

3、突破上面的限制:

和别的网站交互的时候用的。也就是合作的时候

两个办法:

办法一:JSONP,特别机智的方式 原理,动态创建script块,并且添加前台上面去

办法二:cors

JSONP(JSONP - JSON with Padding是JSON的一种“使用模式”),利用script标签的src属性(浏览器允许script标签跨域)
    在客户端需要协商一个函数
            function xx(args){
}
加上标签<script src=”xxx”>
<script>
    xx({“status”:1,”message”:”sasd”},)
</script>
    服务器端:
        {“status”:1,”message”:”sasd”}
        返回给用户:xx({“status”:1,”message”:”sasd”},)
基于jsonp实现跨域ajax
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<input type="button" value="Ajax" onclick="DoAjax();"/>
<input type="button" value="jsonPAjax" onclick="JsonPAjax();"/>

<script src="/statics/jquery.js"></script>
<script src="http://pyrene.com:8002/statics/jquery.cookie.js"></script>
<script>
    function DoAjax(){
        $.ajax({
            url:"http://pyrene.com:8002/index",
            type:"POST",
            //定义对象必须为key/value格式
            data:{"k1":"v1"},

            //下面arg是返回的参数
            success:function(arg){
                console.log(arg);

            }
        })
    }
    function JsonPAjax(){
//        document.createElement("script");
//        tag.src="http://pyrene.com:8002/index";
//        document.head.appendChild(tag);
//        document.head.removeChild(tag)
        //下面是另一种方法,首先跨域访问,之后把访问的函数放到<script>标签内执行
        $.ajax({
            url:"http://pyrene.com:8002/index",
            dataType:"jsonp",
            jsonpCallBack:"func"
        })
    }
</script>

</body>
</html>
html代码
首先要去drivers里面修改hosts

在客户端需要一个函数func,然后访问另一个B服务器端,,B服务器端返回这个函数给这个A服务器的客户端的script标签内,然后通过渲染执行
上面代码流程
#/usr/bin/env python
import tornado.ioloop
import tornado.web
class IndexHnadler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        self.render("index.html")
    def post(self, *args, **kwargs):
        self.write("t3.post")
settings={
    "template_path":"views",
    "static_path":"statics",
    "static_url_prefix":"/statics/"
}
application=tornado.web.Application([
    (r"/index",IndexHnadler),
],**settings)

if __name__=="__main__":
    application.listen(1111)
    tornado.ioloop.IOLoop.instance().start()
端口为1111的服务器python代码
#/usr/bin/env python
import tornado.ioloop
import tornado.web
class IndexHnadler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        self.render("index.html")
    def post(self, *args, **kwargs):
        self.write("t3.post")
settings={
    "template_path":"views",
    "static_path":"statics",
    "static_url_prefix":"/statics/"
}
application=tornado.web.Application([
    (r"/index",IndexHnadler),
],**settings)

if __name__=="__main__":
    application.listen(1111)
    tornado.ioloop.IOLoop.instance().start()
要去访问端口为8002服务器python代码

基于jsonP实现跨域ajax示例之江西卫视节目表

更正式的需要在服务器后台加上下面的两行,即获取客户端用户输入的callback然后在前端代码中获取用户传入的callback和自定义函数,

#/usr/bin/env python
import tornado.ioloop
import tornado.web
class IndexHnadler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        #获取用户传入的callback  这个是需要自定义的
        callback=self.get_argument("callback")
        self.write("%s([11,22,33]);"%callback)
    def post(self, *args, **kwargs):
        self.write("t4.post")
settings={
    "template_path":"views",
    "static_path":"statics",
    "static_url_prefix":"/statics/"
}
application=tornado.web.Application([
    (r"/index",IndexHnadler),
],**settings)

if __name__=="__main__":
    application.listen(8002)
    tornado.ioloop.IOLoop.instance().start()
下面是对江西卫视服务端更合理的补充和修改

下面是调用江西卫视节目单的,前端代码和后台代码

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<input type="button" value="Ajax" onclick="DoAjax();"/>
<input type="button" value="jsonPAjax" onclick="JsonPAjax();"/>
<input type="button" value="jsonPJXAjax" onclick="JsonPJXAjax();"/>

<script src="/statics/jquery.js"></script>
<script src="http://pyrene.com:8002/statics/jquery.cookie.js"></script>
<script>
    //定义函数
    function uo(arg){
        console.log(arg);
    }

    function DoAjax(){
        $.ajax({
            url:"http://pyrene.com:8002/index",
            type:"POST",
            //定义对象必须为key/value格式
            data:{"k1":"v1"},

            //下面arg是返回的参数
            success:function(arg){
                console.log(arg);

            }
        })
    }
    function JsonPAjax(){
//        document.createElement("script");
//        tag.src="http://pyrene.com:8002/index";
//        document.head.appendChild(tag);
//        document.head.removeChild(tag)
        //下面是另一种方法,首先跨域访问,之后把访问的函数放到<script>标签内执行
        $.ajax({
            url:"http://pyrene.com:8002/index",
            dataType:"jsonp",
            //下面这两句相当于在url后面加上?callback=uo
            jsonp:"callback",
            jsonpCallBack:"uo"
        })
    }
    function list(dict){
        console.log(dict);
    }
    function JsonPJXAjax(){
            $.ajax({
            url:"http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list",
            dataType:"jsonp",
            jsonp:"callback",
            jsonpCallBack:"list"
        })
    }
</script>

</body>
</html>
HTML代码
#/usr/bin/env python
import tornado.ioloop
import tornado.web
class IndexHnadler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        self.render("index.html")
    def post(self, *args, **kwargs):
        self.write("t3.post")
settings={
    "template_path":"views",
    "static_path":"statics",
    "static_url_prefix":"/statics/"
}
application=tornado.web.Application([
    (r"/index",IndexHnadler),
],**settings)

if __name__=="__main__":
    application.listen(1111)
    tornado.ioloop.IOLoop.instance().start()
python服务端代码

如果要更加详细的调出节目单,那么直接在前台用一个for循环就可以了

 

 

基于cors实现跨域ajax    跨域资源共享

 

 1 最新浏览器才支持cors功能的,jsonp是现在用的最多的一种
 2 本质: 客户端不变,服务器端设置相应头即可
 3 简单请求:
 4 需要满足下面条件:
 5     1、请求方式:HEAD、GET、POST
 6     2、请求头信息:
 7         Accept
 8         Accept-Language
 9         Content-Language
10         Last-Event-ID
11         Content-Type 对应的值是以下三个中的任意一个
12                                 application/x-www-form-urlencoded
13                                 multipart/form-data
14                                 text/plain
15  
16 注意:同时满足以上两个条件时,则是简单请求,否则为复杂请求
17 
18 简单请求和非简单请求的区别:
19 简单请求:一次请求。
20 非简单请求:两次请求,在发送数据之前会先发一次请求用作与“预检”,只有“预检”通过后才再发送一次请求用于数据传输
21 
22 关于预检:预检都会执行OPTIONS方法
23 请求方式:OPTIONS
24 - “预检”其实做检查,检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息
25 - 如何“预检”
26      => 如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过
27         Access-Control-Request-Method
28      => 如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过
29         Access-Control-Request-Headers

下面就是图示

 

cors实现ajax跨域请求:

简单请求:需要设置响应头:Access-Control-Allow-Origin=”域名 或 *”

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<input type="button" value="Ajax" onclick="DoAjax();"/>
<input type="button" value="DoAjaxComplex" onclick="DoAjaxComplex();"/>
<script src="/statics/jquery.js"></script>
<script>
    function DoAjax(){
        $.ajax({
            url:"http://pyrene.com:8002/cors",
            type:"POST",
            //定义对象必须为key/value格式
            data:{"k1":"v1"},
            //下面arg是返回的参数
            success:function(arg){
                console.log(arg);
            }
        })
    }
HTML代码
class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")
        self.write('{"status": true, "data": "seven"}')
python代码:

支持复杂请求:

复杂请求主要是用options的方法,在options方法中设置如下:

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

  • “预检”请求时,允许请求方式则需服务器设置响应头:Access-Control-Request-Method
  • “预检”请求时,允许请求头则需服务器设置响应头:Access-Control-Request-Headers
  • “预检”缓存时间,服务器设置响应头:Access-Control-Max-Age

如果是put需要设置put方法来接收响应头等

注意在返回来的时候要设置允许网站回来

#/usr/bin/env python
import tornado.ioloop
import tornado.web
class IndexHnadler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        callback=self.get_argument("callback")
        self.write("%s([11,22,33]);"%callback)
    def post(self, *args, **kwargs):
        self.write("t4.post")
class CorsHandler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        self.write('{"status":1,"message":"get"}')
    def post(self, *args, **kwargs):
        self.set_header("Access-Control-Allow-Origin","*")
        self.write('{"status":1,"message":"post"}')
    def options(self, *args, **kwargs):
        print("options")

        #设置允许网站来,这里如果要设置cookie的话,那么下面的域名必须是指定的域名,不能是*了
        # self.set_header("Access-Control-Allow-Origin","*")
        self.set_header("Access-Control-Allow-Origin","http://127.0.0.1:1111")
        #我允许put方法来,设置响应头
        self.set_header("Access-Control-Allow-Methods","PUT,DELETE")
        #我允许请求头
        self.set_header('Access-Control-Allow-Headers', "h1,h2")
        #设置允许带cookie,这个必须要放到预检上面
        self.set_header("Access-Control-Allow-Credentials","true")
        #设置10秒钟只通过一次预检,如果超过10秒钟再来,那么还再一次进行预检
        self.set_header('Access-Control-Max-Age', 10)
        #设置put方法接收
    def put(self, *args, **kwargs):
        print(self.cookies)
        self.set_cookie("k1","aa")
        #设置允许网站回来,如果要携带cookie的时候这里的域名必须是具体的
        # self.set_header("Access-Control-Allow-Origin","*")
        self.set_header("Access-Control-Allow-Origin","http://127.0.0.1:1111")
        #设置允许带cookie
        self.set_header("Access-Control-Allow-Credentials","true")
        self.write("ok")
settings={
    "template_path":"views",
    "static_path":"statics",
    "static_url_prefix":"/statics/"
}
application=tornado.web.Application([
    (r"/index",IndexHnadler),
    (r"/cors",CorsHandler)
],**settings)

if __name__=="__main__":
    application.listen(8002)
    tornado.ioloop.IOLoop.instance().start()
python代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<input type="button" value="Ajax" onclick="DoAjax();"/>
<input type="button" value="DoAjaxComplex" onclick="DoAjaxComplex();"/>
<script src="/statics/jquery.js"></script>
<script>
    function DoAjax(){
        $.ajax({
            url:"http://pyrene.com:8002/cors",
            type:"POST",
            //定义对象必须为key/value格式
            data:{"k1":"v1"},
            //下面arg是返回的参数
            success:function(arg){
                console.log(arg);
            }
        })
    }
    function DoAjaxComplex(){
        $.ajax({
            url:"http://pyrene.com:8002/cors",
            type:"PUT",
            //设置请求头
            headers:{"h1":"hh"},
            //定义对象必须为key/value格式
            data:{"k1":"v1"},
            //下面表示程序想要携带cookie
            xhrFields:{withCredentials: true},
            //下面arg是返回的参数
            success:function(arg){
                console.log(arg);
            }
        })
    }
</script>
</body>
</html>
html代码

跨站传输cookie

 

在HTML中设置
//下面表示程序想要携带cookie
xhrFields:{withCredentials: true},
在服务器后台中设置:这里注意把允许网站回来中的域名不能是
*

 即:服务器端响应的 Access-Control-Allow-Origin 不能是通配符 *


#设置允许带cookie,这个必须要放到预检上面
self.set_header("Access-Control-Allow-Credentials","true")
在put方法中,这里注意把允许网站回来中的域名不能是
* #设置允许带cookie self.set_header("Access-Control-Allow-Credentials","true")

 

posted @ 2017-04-14 16:46  pyrene  阅读(244)  评论(0编辑  收藏  举报