浏览器的跨域解决方案

一. jsonp解决跨域问题css

  1. 函数中传参html

    dom1中的HTMLjquery

<!DOCTYPE HTML>
<html>
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>xyz</title>
</head>
<body>
<button id="b1">点我</button>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>
  function rion(res) { console.log(res); } </script>
<script src="http://127.0.0.1:8002/abc/"></script>
</body>
</html>

  demo2 中的视图函数:git

def abc(request): res = {"code": 0, "data": ["SNIS-561", "SNIS-517", "SNIS-539"]} return HttpResponse("rion({})".format(json.dumps(res)))

  JQuery中getJSON方法:github

    demo2中HTMLdjango

<!DOCTYPE HTML>
<html>
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>xyz</title>
</head>
<body>
<button id="b1">点我</button>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script> $("#b1").click(function () { $.getJSON("http://127.0.0.1:8002/abc/?callback=?", function (res) { console.log(res); }) }); </script>
</body>
</html>

  

  要注意的是在url的后面必需要有一个callback参数,这样getJSON方法才会知道是用JSONP方式去访问服务,callback后面的那个?是jQuery内部自动生成的一个回调函数名。json

 

 

二. CORS解决跨域问题后端

  CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它容许浏览器向跨源服务器发出XMLHttpRequest请求,从而解决AJAX只能同源使用的限制.跨域

  浏览器将CORS请求分为两类: 简单请求非简单请求浏览器

  一个请求须要同时知足 如下两大条件 才属于简单请求.

(1) 请求方法是如下三种方法之一:     HEAD     GET     POST (2)HTTP的头信息不超出如下几种字段:     Accept     Accept-Language     Content-Language     Last-Event-ID     Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

简单请求的处理方式

 在跨域场景下,当浏览器发送简单请求时,浏览器会自动在请求头中添加代表请求来源的 Origin 字段。

  

  咱们的后端程序只须要在返回的响应头中加上 Access-Control-Allow-Origin 字段,而且把该字段的值设置为 跨域请求的来源地址或简单的设置为 * 就能够了。

例如:咱们能够在Django中间件中的process_response方法来给相应对象添加该字段。

from django.utils.deprecation import MiddlewareMixin class CorsMiddleware(MiddlewareMixin): def process_response(self, request, response): # 给响应头加上 Access-Control-Allow-Origin 字段 并简单的设置为 * response['Access-Control-Allow-Origin'] = '*' return response

 

非简单请求的处理方式 >>  

  咱们开发中经常使用到的那些请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json的都是非简单请求。

 

  对于非简单请求,浏览器一般都会在请求以前发送一次 OPTIONS 预检 请求。该请求会像后端服务询问是否容许从当前源发送请求而且询问容许的 请求方法 和 请求头字段

  

解决方案在上面Django的中间件中添加以下代码:

from django.utils.deprecation import MiddlewareMixin class CorsMiddleware(MiddlewareMixin): def process_response(self, request, response): # 给响应头加上 Access-Control-Allow-Origin 字段 并简单的设置为 * response['Access-Control-Allow-Origin'] = '*' if request.method == 'OPTIONS': # 容许发送 PUT 请求 response['Access-Control-Allow-Methods'] = 'PUT, DELETE' # 容许在请求头中携带 Content-type字段,从而支持发送json数据 response['Access-Control-Allow-Headers'] = 'Content-type' return response

 

 

三. 使用 Django-corset-headers 解决跨域问题

  

咱们这个中间件确实能解决目前的CORS跨域问题,可是咱们的土方法确定是不够严谨的,已经有人造好轮子-- django-cors-headers 了。

 

咱们只须要安装这个包,而后按须要配置一下就能够了。

 

安装

 

pip install django-cors-headers

 

注册APP

 

INSTALLED_APPS = [
    ...
    'app01.apps.App01Config',
    'corsheaders',  # 将 corsheaders 这个APP注册
]

 

添加中间件

 

必须放在最前面,由于要先解决跨域的问题。只有容许跨域请求,后续的中间件才会正常执行。

 

复制代码
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',
]
复制代码

 

配置

 

你能够选择不限制跨域访问

 

CORS_ORIGIN_ALLOW_ALL = True

 

或者你能够选择设置容许访问的白名单

 

CORS_ORIGIN_ALLOW_ALL = False
CORS_ORIGIN_WHITELIST = (
    # '<YOUR_DOMAIN>[:PORT]',
    '127.0.0.1:8080'
)

 

更多详细配置详细请查看django-cors-headers项目

相关文章
相关标签/搜索