什么是跨域?
- 跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。
- ajax或者iframe指向的地址中,二级域名、端口、协议必须与主页面完全相同,否则就算跨域
比如
- a.baidu.com访问b.baidu.com 是跨域;
- a.baidu.com:8080访问a.baidu.com:80 是跨域;
- http://a.baidu.com访问https://a.baidu.com 是跨域
请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。
浏览器执行javascript脚本时,会检查这个脚本属于哪个页面,如果不是同源页面,就不会被执行。
方法一:
安装:
pip install flask_cors
pycharm 安装 flask-cors
初始化的时候加载配置,这样就可以支持跨域访问了
from flask_cors import CORS
app = Flask(__name__)
CORS(app, supports_credentials=True)
if __name__ == "__main__":
app.run()
方法二:
安装:
pip install flask_cors
对请求的Response header中加入header
from flask_cors import CORS
@app.after_request
def af_request(resp):
"""
#请求钩子,在所有的请求发生后执行,加入headers。
:param resp:
:return:
"""
resp = make_response(resp)
resp.headers['Access-Control-Allow-Origin'] = '*'
resp.headers['Access-Control-Allow-Methods'] = 'GET,POST'
resp.headers['Access-Control-Allow-Headers'] = 'x-requested-with,content-type'
return resp
解决App打包编译以后的跨域限制
解决app打包生成以后,页面无法请求服务端数据的跨域问题。
无法获取数据的原因是,当前APP中获取数据是通过ajax来发送请求的,因为我们当前的APP是混合APP,所以实际来说,这种混合APP就是一个浏览器内核构建的。因此也会存在同源策略的访问限制,因此我们需要在服务端实现跨域资源共享。
服务端终端运行:
pip install -U flask-cors
代码:
import os,sys
from flask import Flask
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy
from flask_redis import FlaskRedis
from flask_session import Session
from flask_migrate import Migrate,MigrateCommand
from flask_jsonrpc import JSONRPC
from flask_marshmallow import Marshmallow
from flask_jwt_extended import JWTManager
from flask_admin import Admin
from flask_babelex import Babel
from faker import Faker
from flask_pymongo import PyMongo
from flask_qrcode import QRcode
from flask_socketio import SocketIO
from flask_cors import CORS
from application.utils import init_blueprint
from application.utils.config import load_config
from application.utils.session import init_session
from application.utils.logger import Log
from application.utils.commands import load_command
# 创建终端脚本管理对象
manager = Manager()
# 创建数据库链接对象
db = SQLAlchemy()
# redis链接对象
redis = FlaskRedis()
# Session存储对象
session_store = Session()
# 数据迁移实例对象
migrate = Migrate()
# 日志对象
log = Log()
# jsonrpc模块实例对象
jsonrpc = JSONRPC()
# 数据转换器的对象创建
ma = Marshmallow()
# jwt认证模块实例化
jwt = JWTManager()
# flask-admin模块实例化
admin = Admin()
# flask-babelex模块实例化
babel = Babel()
# mongoDB
mongo = PyMongo()
# qrcode
QRCode = QRcode()
# socketio
socketio = SocketIO()
# flask_cors
cors = CORS()
def init_app(config_path):
"""全局初始化"""
# 创建app应用对象
app = Flask(__name__)
# 项目根目录
app.BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 加载导包路径
sys.path.insert(0, os.path.join(app.BASE_DIR,"application/utils/language"))
# 加载配置
Config = load_config(config_path)
app.config.from_object(Config)
# 数据库初始化
db.init_app(app)
app.db = db
redis.init_app(app)
mongo.init_app(app)
# 数据转换器的初始化
ma.init_app(app)
# session存储初始化
init_session(app)
session_store.init_app(app)
# 数据迁移初始化
migrate.init_app(app,db)
# 添加数据迁移的命令到终端脚本工具中
manager.add_command('db', MigrateCommand)
# 日志初始化
app.log = log.init_app(app)
# 蓝图注册
init_blueprint(app)
# jsonrpc初始化
jsonrpc.service_url = "/api" # api接口的url地址前缀
jsonrpc.init_app(app)
# jwt初始化
jwt.init_app(app)
# admin初始化
admin.init_app(app)
# 国际化本地化模块的初始化
babel.init_app(app)
# 初始化终端脚本工具
manager.app = app
# 数据种子生成器[faker]
app.faker = Faker(app.config.get("LANGUAGE"))
# qrcode初始化配置
QRCode.init_app(app)
# cors
cors.init_app(app,resources={r"/api/*": {"origins": "*"}})
# socketio
socketio.init_app(app, cors_allowed_origins=app.config["CORS_ALLOWED_ORIGINS"],async_mode=app.config["ASYNC_MODE"], debug=app.config["DEBUG"])
# 改写runserver命令
if sys.argv[1] == "runserver":
manager.add_command("run", socketio.run(app,host=app.config["HOST"],port=app.config["PORT"]))
# 注册自定义命令
load_command(manager)
return manager