赞
踩
在前面的学习中,我们都是在本地起服务,再在本地访问资源及界面,但是实际当中都是开启多台服务器,提供给局域网外的用户访问。这就牵涉到了跨域问题,跨域问题来源于同源策略,同源策略是一种约定,是浏览器最核心以及最基本的安全功能,它要求在使用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
解决方法二:ajax跨域请求方案
优点:兼容性强,适用于所有浏览器
缺点:
用法:
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');
}
});
后端:
jsonpCallback = request.args.get("jsonCallback");
解决方法五:后端处理,使用第三方扩展 https://pypi.org (推荐)
1、安装 pip install flask-cors
2、exts中定义
cors = CORS()
3、初始化
def create_app():
...
cors.init_app(app=app,supports_credentials=True)
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()
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
本地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')
另一台电脑调用接口数据并展示
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('<p>'+data[i].name+'</p>') } }); }); </script> </html>

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。