- 前后端分离开发减少项目间的耦合度,前端开发只需要专注于页面实现,后端则只需负责相关接口开发,分工明确。前后端分离项目也就意味着前后端项目独立分开部署,所以会遇到跨域问题。
- 浏览器的同源策略
所谓同源是指 域名 协议 端口均相同 - 跨域产生场景
1)非跨域,符合同源策略
http://www.1yl.com/show.html 调用 http://www.1yl.com/web
2)跨域,主域名不同 1yl/abc
http://www.1yl.com/show.html 调用 http://www.abc.com/web
3)跨域,子域名不同 ef/abc
http://www.ef.1yl.com/show.html 调用 http://www.abc.1yl.com/web
4)跨域,端口号不同 8080/8081
http://www.1yl.com:8080/show.html 调用 http://www.1yl.com:8081/web
5)跨域,协议不同 http/https
http://www.1yl.com/show.html 调用 https://www.1yl.com/web
6)跨域,本机localhost/127.0.0.1
http://localhost:8080/show.html 调用 http://127.0.0.1:8080/web - 跨域解决方法
1.jsonp
类似前端js文件中写一段代码作为执行脚本
2.CORS(Cross-Origin Resource Sharing 跨域资源共享)
前端欲通过后端API获取数据,则需后端在API访问之前编写中间件或工厂函数来解决跨域
如:Django
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# # 分页
# REST_FRAMEWORK = {
# 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
# 'PAGE_SIZE': 10, # 每页数目
# }
# 允许所有域名跨域
CORS_ORIGIN_ALLOW_ALL = True
# 允许携带cookie:
CORS_ALLOW_CREDENTIALS = True
# 允许ip访问站点(*代表所有其他请求都可以访问)
# CORS_ORIGIN_WHITELIST = (
# '*'
# )
# 允许请求的方法
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)
# 允许请求头的字段类型
CORS_ALLOW_HEADERS = (
'XMLHttpRequest',
'X_FILENAME',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
'Pragma',
)
如: Flask
# 工厂函数:一个封装创建实例过程函数
def create_app(config_filename):
app = Flask(__name__)
app.register_blueprint(user)
app.register_blueprint(task)
app.register_blueprint(web)
app.config.from_object(config_filename)
@app.after_request
def after_request(response):
response.headers.add('Access-Control-Allow-Origin', '*')
if request.method == 'OPTIONS':
response.headers['Access-Control-Allow-Methods'] = 'DELETE, GET, PUT, POST'
headers = request.headers.get('Access-Control-Request-Headers')
if headers:
response.headers['Access-Control-Allow-Headers'] = headers
return response
# from app.user.api import init_api
# init_api(app)
return app
3.Nginx反向代理
这是本地的开发环境nginx的配置
http {
client_max_body_size 1024m;
include mime.types;
default_type application/octet-stream;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 8081; #自身监听8081端口
server_name first;
location /apis/xos {
#当匹配到/apis/xos 地址是时访问 http://172.99.99.99:31004/
proxy_pass http://172.99.99.99:31004/;
}
location /apis/rds {
#当匹配到/apis/rds 地址是时访问 http://172.88.88.88:20152
proxy_pass http://172.88.88.88:20152/;
}
location /apis {
#当匹配到/apis 地址是时访问 http://172.88.88.88:31002/,一个api地址
proxy_pass http://172.88.88.88:31002/;
}
location / {
proxy_pass http://127.0.0.1:8080; #匹配不到其他地址默认匹配的地址是访问 8080端口,本地node start启动的服务
}
}
}