• flask框架初学-11-解决跨域问题


    在前面的学习中,我们都是在本地起服务,再在本地访问资源及界面,但是实际当中都是开启多台服务器,提供给局域网外的用户访问。这就牵涉到了跨域问题,跨域问题来源于同源策略,同源策略是一种约定,是浏览器最核心以及最基本的安全功能,它要求在使用JavaScript的浏览器中,只有协议+主机名+端口号(如存在)相同的两个URL才能互相访问,这样的限定可以减少恶意文档以及可能被攻击的媒介。但是却限定了浏览器只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。本章将会介绍如何解决这个问题。

    目前解决跨域问题常见的方法有以下四种:

    1、响应头添加Header允许访问

    2、ajax跨域请求方案

    3、httpClient内部转发

    4、使用接口网关-nginx、springcloud zuul

    5、跨域资源共享(CROS)

    5、后端处理,使用第三方扩展 https://pypi.org (推荐)

    解决方法一:响应头添加Header允许访问

    response = make_response()
    # 允许接收所有Origin
    response.header['Access-Control-Allow-Origin']='*'
    # 允许接收GET,POST类型的URL
    response.header['Access-Control-Allow-Methods']='GET,POST'
    # 允许接收x-request-with,Content-type头部信息的URL
    response.header['Access-Control-Allow-Headers']='x-request-with,Content-type'
    return response
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    解决方法二:ajax跨域请求方案

    优点:兼容性强,适用于所有浏览器

    缺点:

    • 没有关于调用错误的处理
    • 只支持GET请求,不支持POST以及大数据量的请求,也无法拿到相关的返回头,状态码等数据
    • callback参数恶意注入,可能会造成xss漏洞
    • 无法设置资源访问权限

    用法:
    1、dataType改为jsonp

    2、jsonp:“jsonpCallback”—>发送到后端实际为http://a.a.com/a/FromSerclet?username=644064&jsonpCallback=jQueryXXX

    3、后端获取get请求中的jsonCallback

    4、构造回调结构

    5、后端处理,使用第三方扩展 https://pypi.org (推荐)

    前端:

    $.ajax({
        type: "GET",
        async: false,
        url: "http://a.a.com/a/FromSerclet?username=644064",
        dataType:"jsonp", //数据类型为jsonp
        jsonp: "jsonpCallback",  //服务端用于修改callback调用的function名的参数
        success: function(data){
            alert(data["username"]);
            ),
            error: function(){
                alert('fail');
        }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    后端:

    jsonpCallback = request.args.get("jsonCallback");
    
    • 1

    解决方法五:后端处理,使用第三方扩展 https://pypi.org (推荐)

    1、安装 pip install flask-cors
    2、exts中定义

    cors = CORS()
    
    • 1

    3、初始化

    def create_app():
         ...
         cors.init_app(app=app,supports_credentials=True)
    
    • 1
    • 2
    • 3

    Example

    exts下的init.py

    from flask_caching import Cache
    from flask_cors import CORS
    from flask_restful import Api
    from flask_sqlalchemy import SQLAlchemy
    import pymysql
    pymysql.install_as_MySQLdb()
    
    db = SQLAlchemy()
    cors = CORS()
    cache = Cache()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    app下的init.py

    from flask import Flask
    from app.apis.news_api import news_bp
    from app.apis.user_api import user_bp
    from exts import db, cors, cache
    from settings import DevelopmentConfig
    
    config = {
        'CACHE_TYPE': 'redis',
        'CACHE_REDIS_HOST': '127.0.0.1',
        'CACHE_REDIS_PORT': 6379
    }
    
    def create_app():
        app = Flask(__name__,static_folder='../static',template_folder='../templates')
        app.config.from_object(DevelopmentConfig)
    
        db.init_app(app=app)
        cors.init_app(app=app,supports_credentials=True)
        cache.init_app(app=app,config=config)
        app.register_blueprint(news_bp)
        app.register_blueprint(user_bp)
    
        return app
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    本地news_api.py

    from flask import Blueprint, app, g
    from flask_restful import Api, Resource, fields, marshal_with, reqparse, marshal
    
    from app.models.news_model import NewsType, News
    
    news_bp = Blueprint('news',__name__,url_prefix='/news')
    api = Api(news_bp)
    
    # 新闻类型输出格式
    types_fields = {
        'id': fields.Integer,
        'name': fields.String(attribute='type_name')
    }
    
    # 新闻类型api
    class NewsTypeApi(Resource):
        @marshal_with(types_fields)
        def get(self):
            types = NewsType.query.all()
            # print(app.url_map)
            return types
        
        
    api.add_resource(NewsTypeApi,'/types')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    另一台电脑调用接口数据并展示

    index.html

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>首页title>
        <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js">script>
    head>
    <style>
        #container{
            border: 1px solid red;
        }
        #container p{
            font-size: 20px;
            color: deepskyblue;
            font-weight: bold;
        }
    style>
    <body>
        <div id="container">
    
        div>
    body>
    <script>
        $(function(){
            url = 'http://IP地址:5000/news/types';
            $.get(url,function(data){
              //  console.log(data);
              //  console.log(typeof data);
                for (i = 0; i < data.length; i++){
                  //  console.log(data[i].name)
                    $('#container').append('

    '+data[i].name+'

    '
    ) } }); });
    script> html>
    • 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
    • 32
    • 33
    • 34
    • 35
    • 36

    在这里插入图片描述

  • 相关阅读:
    python安装源码包
    hadoop测试环境sqoop使用
    SpringSecurity系列——认证(Authentication)架构day2-3(源于官网5.7.2版本)
    解决Mysql8.0不存在mysql.proc表
    【UGUI】给美术的备忘录
    艾美捷PEG化蛋白ELISA试剂盒—高度灵敏度,高通量格式!
    python数组处理方法
    二次开发入门须知
    要想后期修改少,代码重构要趁早
    07_sentinel—QPS—流控规则
  • 原文地址:https://blog.csdn.net/weixin_42724501/article/details/126366039