Python Web 框架-Ajax day10

目录

1.JQ 对 ajax的支持

2.跨域(Cross Domain)


day09回顾

1.前后端处理JSON

  1. 后端处理
    import json
    json.dumps(列表|元组|字典)
    class Model(db.Model):
        ...
        def to_dict(self):
            dic = {
                ...

            }
            return dic
  2. 前端处理
    var jsonObj = JSON.parse(JSON串)

2.JQ 对 ajax 支持

  1. $obj.load()
    语法:$obj.load(url,data,callback)
  2. $.get()
    语法:$.get(url,data,callback,type)
    $.get('/01-server',function(data){
      data就是JSON格式
    },'json')
  3. $.port()

1.JQ 对 ajax的支持

  1. $.ajax()
    语法:$.ajax({请求参数的JSON对象});
    参数对象中的属性:
    1. url:字符串,表示异步请求的地址
    2. type:字符串,请求方式,get 或 post
    3. data:传递到服务器端的参数
      可以是字符串 :‘name=sf.zh&age=18’
      也可以是JSON对象:
      {
        'name':'sf.zh',
        'age':18
      }
    4. dataType:字符串,响应回来的数据的格式
      1. ‘html’
      2. 'xml'
      3. 'text'
      4. 'script'
      5. 'json'
      6. 'jsonp':有关跨域的响应格式
    5. success:回调函数,请求和响应成功时回来执行的操作
      ---------------------------------------------------------------------------
    6. error:回调函数,请求或响应失败时回来执行的操作
    7. beforeSend:回调函数,发送ajax请求之前执行的操作,如果是return false,则终止请求发送

2.跨域(Cross Domain)

  1. 什么是跨域
    HTTP协议中有一个策略 - ‘同源策略’
      同源:多个地址中,相同协议,相同域名,相同端口被视为是‘同源’
      在HTTP中,必须是同源地址才能互相发送请求,非同源拒绝请求(<script>和<img>除外)。

      http://www.tedu.cn/a.html
      http://www.tedu.cn/b.html
      以上地址是同源

      https://www.tedu.cn/a.html
      http://www.tedu.cn/b.html
      由于协议不同,所以不是‘同源’

      http://localhost/a.html
      http://127.0.0.1/a.html
      由于域名不同,所以不是‘同源’

      http://www.tedu.cn:80/a.html
      http://www.tedu.cn:8000/b.html
      由于端口不同,所以不是‘同源’

    跨域:非同源的网页,相互发送请求的过程,就是跨域
  2. 解决方案
    通过<script> 向服务器资源发送请求
    由服务器资源指定前端页面的哪个方法来执行响应的数据
    示例06-crossdomain.html / 07-flight.html
  3. jquery 的跨域


    $.ajax({
      url:'xxx',
      type:'get',
      dataType:'jsonp', //指定为跨域访问
      jsonp:'callback', //定义了callback的参数名,以便获取callback传递过去的函数名
      jsonpCallback:'xxx' //定义jsonp的回调函数名
    });

今日示例:

AjaxDemo2.py

from flask import Flask, render_template, request
import json
from flask_sqlalchemy import SQLAlchemy
import pymysql
pymysql.install_as_MySQLdb()

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']="mysql://root:123456@localhost:3306/flask"
db = SQLAlchemy(app)

class Users(db.Model):
  __tablename__ = "users"
  id = db.Column(db.Integer,primary_key=True)
  uname = db.Column(db.String(50))
  upwd = db.Column(db.String(50))
  realname = db.Column(db.String(30))

  # 将当前对象中的所有属性封装到一个字典中
  def to_dict(self):
    dic = {
      'id':self.id,
      'uname':self.uname,
      'upwd':self.upwd,
      'realname':self.realname
    }
    return dic


  def __repr__(self):
    return "<Users:%r>" % self.uname


class Province(db.Model):
  __tablename__ = "province"
  id = db.Column(db.Integer,primary_key=True)
  proname = db.Column(db.String(30),nullable=False)
  cities = db.relationship('City',backref='province',lazy='dynamic')

  def to_dict(self):
    dic = {
      'id' : self.id,
      'proname':self.proname
    }
    return dic

  def __init__(self,proname):
    self.proname = proname

  def __repr__(self):
    return "<Province:%r>" % self.proname

class City(db.Model):
  __tablename__ = "city"
  id = db.Column(db.Integer,primary_key=True)
  cityname = db.Column(db.String(30),nullable=False)
  pro_id = db.Column(db.Integer,db.ForeignKey("province.id"))

  def to_dict(self):
    dic = {
      'id' : self.id,
      'cityname' : self.cityname,
      'pro_id' : self.pro_id,
    }
    return dic

  def __init__(self,cityname,pro_id):
    self.cityname = cityname
    self.pro_id = pro_id

  def __repr__(self):
    return "<City:%r>" % self.cityname

db.create_all()




@app.route('/02-province')
def province_views():
  return render_template('02-province.html')

@app.route('/02-loadPro')
def loadPro_views():
  provinces = Province.query.all()
  list = []
  for pro in provinces:
    list.append(pro.to_dict())
  return json.dumps(list)

@app.route('/02-loadCity')
def loadCity_views():
  # 接收前端传递过来的数据,pid为前端传递过来的参数名
  pid = request.args.get('pid')
  cities = City.query.filter_by(pro_id=pid).all()
  list = []
  for city in cities:
    list.append(city.to_dict())
  return json.dumps(list)



######### 2018.10.09########
@app.route("/05-server")
def server_05():
  uname = request.args.get('uname')
  u = Users.query.filter_by(uname=uname).first()
  if u :
    return json.dumps(u.to_dict())
  else:
    dic = {
      'status' : "0",
      'msg' : '查找的用户不存在'
    }
    return json.dumps(dic)


@app.route('/06-server')
def server_06():
  # 接收前端传递过来的callback即前端处理响应数据的函数名
  cb = request.args.get('callback')
  #响应数据,被前端页面当成JS脚本被执行
  return cb+"('这是server_06响应回来的数据')"

@app.route('/07-server')
def server_07():
  cb = request.args.get('callback')
  dic = {
    'flightNO':'MU763',
    'from':'Beijing',
    'to':'Saipan',
    'time':'16:55'
  }
  # flight({'flightNO':'MU763'...})
  return cb+"("+json.dumps(dic)+")"


if __name__ == '__main__':
  app.run(debug=True)

02-province.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="/static/js/common.js"></script>
  <script src="/static/js/jquery-1.11.3.js"></script>
  <script>

    function loadPro(){
      /*var xhr = createXhr();
      //false : 表示采用同步的方式执行,必须保证loadPro()执完毕之后才能执行其他的操作
      xhr.open('get','/02-loadPro',false);
      xhr.onreadystatechange = function(){
        if(xhr.readyState==4 && xhr.status==200){
          var arr = JSON.parse(xhr.responseText);
          var html = "";
          $.each(arr,function(i,obj){
            html += "<option value='"+obj.id+"'>";
            html += obj.proname;
            html += "</option>";
          });
          $("#selPro").html(html);
        }
      }
      xhr.send(null);*/

      //使用 $.ajax()
      $.ajax({
        url:'/02-loadPro',
        type:'get',
        dataType:'json',
        async:false, //异步
        success:function(data){
          var html="";
          $.each(data,function(i,obj){
            html += "<option value='"+obj.id+"'>";
            html += obj.proname;
            html += "</option>";
          });
          $("#selPro").html(html);
        }
      });
    }

    /**
     * 根据省份的id查询对应的所有的城市信息
     * 参数pid:要查询的省份的id
     * */
    function loadCity(pid){
      /*var xhr = createXhr();
      var url = '/02-loadCity?pid='+pid;
      xhr.open('get',url,true);
      xhr.onreadystatechange = function(){
        if(xhr.readyState==4&&xhr.status == 200){
          var arr = JSON.parse(xhr.responseText);
          var html = "";
          $.each(arr,function(i,obj){
            html+="<option value='"+obj.id+"'>";
            html+=obj.cityname;
            html+="</option>";
          });
          $("#selCity").html(html);
        }
      }
      xhr.send(null);*/

      //使用$.get()
      $.get(
        "/02-loadCity",
        {'pid':pid},
        function(data){
          var html = "";
          $.each(data,function(i,obj){
            html+="<option value='"+obj.id+"'>";
            html+=obj.cityname;
            html+="</option>";
          });
          $("#selCity").html(html);
        },'json');
    }

    $(function(){
      /**加载所有的省份信息*/
      loadPro();
      /**为selPro绑定change事件*/
      $("#selPro").change(function(){
        loadCity(this.value);
      });
      /**调用loadCity(),先将默认的城市加载进来*/
      console.log($("#selPro").val());
      loadCity($("#selPro").val());

    });

  </script>
</head>
<body>
  <select id="selPro">

  </select>

  <select id="selCity"></select>
</body>
</html>

05-ajax.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/jquery-1.11.3.js"></script>
</head>
<body>
{% if uname %}
    {{ uname }}
{% endif %}
<h1>这是静态网页</h1>
<p>
    用户名:<input type="text" id="uname">
</p>
<button id="btnAjax">ajax查询</button>
<p id="show"></p>
<script>
    $(function(){
        $("#btnAjax").click(function(){
            //使用get请求方式,发送参数名为uname的数据到服务器
            $.ajax({
                //请求地址
                url:'/05-server',
                //请求方式
                type:'get',
                //请求参数
                data:"uname="+$("#uname").val(),
                //响应回来的数据格式
                dataType:'json',
                //请求和响应成功之后的回调函数
                success:function(data){
                    var html="";
                    if(data.id){
                        //如果data中有id属性,则说明查询成功
                        html+="<h3>id:"+data.id+"</h3>";
                        html+="<h3>username:"+data.uname+"</h3>";
                        html+="<h3>age:"+data.upwd+"</h3>";
                        html+="<h3>email:"+data.realname+"</h3>";
                    }else{
                        //data中没有id属性,说明查询失败
                        html+="<h3>"+data.msg+"</h3>";
                        html+="<h3>"+data.status+"</h3>"
                    }
                    $("#show").html(html);
                }
            });
        }) ;
    });
</script>
</body>
</html>

06-crossdomain.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>跨域</title>
  <script src="js/jquery-1.11.3.js"></script>
</head>
<body>
  <button id="btn">跨域请求</button>
  <div id="show"></div>
  <script>
    /**
     * 跨域调用的方法,由服务器端来指定调用
     * */
    function print(data){
      console.log("服务器端传递的数据:"+data);
    }

    $(function(){
      $("#btn").click(function(){
        //正常的ajax请求无法完成跨域访问
        /*var url = "http://127.0.0.1:5000/06-server"
        $.get(url,function(data){
          $("#show").html(data);
        });*/

        //原生的js完成跨域请求
        //获取页面上的body标签
        var body = document.getElementsByTagName("body")[0];
        //动态的创建一对script标记,来完成js的请求,
        //通过<script>产生的请求,响应回来的数据一律当成js脚本被执行
        var script = document.createElement("script");
        //为script标记的type属性赋值
        script.type = "text/javascript"
        //指定script标记的请求地址,callback参数表示告诉后端前端处理响应数据的函数名
        script.src = "http://127.0.0.1:5000/06-server?callback=print";
        //将script标记追加到当前页面:也就是向src的地址发送请求,同时接收响应数据,响应数据直接交给了页面,由页面当成js的脚本去执行
        body.append(script);

        //return "show('这是server_06响应回来的数据')"
      });
    });

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

07-flight.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="js/jquery-1.11.3.js"></script>
</head>
<body>
  <button id="btnShow">显示</button>
  <div id="show"></div>
  <script>
    function flight(data){
      html = "";
      html += "<h3>航班号:"+data.flightNO+"</h3>";
      html += "<h3>出发:"+data.from+"</h3>";
      html += "<h3>到达:"+data.to+"</h3>";
      html += "<h3>时间:"+data.time+"</h3>";
      $("#show").html(html);
    }

    $(function(){
      $("#btnShow").click(function(){
        //原生的跨域请求
        /*var body = document.getElementsByTagName("body")[0];
        var script = document.createElement("script");
        script.type = "text/javascript"
        script.src = "http://127.0.0.1:5000/07-server?callback=flight";
        body.append(script);*/

        //jquery跨域请求 - jsonp
        /*$.ajax({
          url : 'http://127.0.0.1:5000/07-server',
          type : 'get',
          dataType : "jsonp",
          jsonp:'callback',
          jsonpCallback:'flight'
        });*/

        //jquery 跨域请求 - jsonp (简易版)
        $.ajax({
          url : 'http://127.0.0.1:5000/07-server',
          type : 'get',
          dataType : 'jsonp',
          success:function(data){
            console.log("航班:"+data.flightNO);
            console.log("出发:"+data.from);
            console.log("到达:"+data.to);
            console.log("时间:"+data.time);
          }
        });
      });
    });
  </script>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/qq_42584444/article/details/82977152
今日推荐