• django中的跨域问题以及解决策略


    目录

    跨域请求

    同源策略

    CORS(跨域资源共享)简介

    CORS基本流程

    解决跨域问题的方法

    CORS两种请求详解

    预检:

    解决跨域问题(服务端)

    简单请求

     非简单请求

    解决跨域问题(第三方)

    后端配置

    解决跨域问题(前端)


    跨域请求

    跨域是指浏览器不能执行其他网站的脚本, 它是由浏览器的同源策略造成的,,是浏览器对javascript 实施的安全限制。 

    浏览器从一个域名的网页请求去另一个域名的资源时,出现域名,端口,协议任意一个不同就属于跨域

    部署时前后端不分离可以解决此问题【但是不推荐】

    同源策略

    同源策略是浏览器为了保护用户信息安全的一种安全政策。 指的是iu篮球页面的协议, 域名,端口号都相同,其目的是为了保证用户的信息安全,防止恶意网站盗取数据信息。 

    不同源的客户端脚本js在没有得到服务端的明确授权的情况下,浏览器会显示拒绝提供服务给前端ajax/axios。

    CORS(跨域资源共享)简介

    CORS是一个W3C标准,全程跨域资源共享。 它允许浏览器向跨源的后端服务器发出ajax请求,

    从而克服了AJAX只能同源使用的限制。

    实现CORS主要一开后端服务器响应数据中设置响应头信息返回的CORS需要浏览器和服务器同时支持, 目前除了IE浏览器都支持该功能

    整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

    因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信

    容易混淆的点:

    • CORS:跨域资源共享
    • CSRF: 跨站请求伪造
    • XSS: 跨站脚本攻击

    CORS基本流程

    浏览器讲CORS请求分成两类: 简单请求(simple request) 和 非简单请求(not-so-simple-request)

    浏览器发出CORS简单请求只需要在头信息中增加Origin字段

    浏览器发出非简单CORS请求, 会在正式通信之前增加一次Http查询请求,即’预检‘请求。

    浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之内,以及跨源使用那些Http动词和头信息字段

    只有的带肯定答复,溜啦冷凝器才会发出正式的XMLHttpRequest请求,否则就会报错。 

    解决跨域问题的方法

    前端: 通过代理解决

    nginx代理

    cors解决跨域:django-cors-headers

    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

    凡是不能同时满足以上两个条件就属于非简单请求

    json格式是非简单请求

    浏览器对这两种请求的处理是不一样的

    简单请求和非简单请求的区别

    简单请求:之发送一次请求

    非简单请求: 发送2次请求,在发送数据之前会先发一次请求用于做’预检‘看后端是否允许,只有预检通过之后才会再次发送请求用于数据传输

    请求方式OPTIONS

    预检:

    如果非简单请求是PUT等请求, 则服务端需要设置允许某请求,否则预检不通过

    • Access-Control-Request-Method

    如果非简单请求设置了请求头, 则服务端需要设置允许某请求头,否则预检不通过

    • Access-Control-Request-Headers

    解决跨域问题(服务端)

    简单请求

    Django项目: apps/user/views.py

    1. from django.http import JsonResponse
    2. def test(request):
    3. obj = JsonResponse({'name': 'darker', 'age': '18'})
    4. # 值针对简单请求
    5. obj['Access-Control-Allow-Origin'] = '*' # 允许所有IP访问
    6. return obj

    2, 原 django项目: apps/user/urls.py

    1. from django.urls import path
    2. from user import views
    3. urlpatterns = [
    4. path('test/', views.test),
    5. ]

    3. django项目中注释掉dev.py中的CSRF

    4, 再创建一个django项目(用另一个端口)

    template中创建index。html

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>Titletitle>
    6. <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js">script>
    7. head>
    8. <body>
    9. <button id="btn">点我button>
    10. body>
    11. <script>
    12. $('#btn').click(function () {
    13. $.ajax({
    14. url: 'http://127.0.0.1:8000/user/test/',
    15. method: 'get',
    16. success: function (data) {
    17. console.log(data)
    18. }
    19. })
    20. })
    21. script>
    22. html>

    views.py

    1. from django.shortcuts import render
    2. def index(request):
    3. return render(request, 'index.html')

    urls.py

    1. from django.urls import path
    2. from app01 import views
    3. urlpatterns = [
    4. path('test/', views.index),
    5. ]

     非简单请求

    原django项目 app/user/view.py

    1. from django.http import JsonResponse
    2. def test(request):
    3. obj = JsonResponse({'name': 'Darker', 'age': '18'})
    4. if request.method == 'OPTIONS':
    5. obj['Access-Control-Allow-Headers'] = 'Content-Type,authorization' # 或者填写 *
    6. obj['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8002' # 8002端口是当前项目的
    7. return obj

     新django项目中 template/index.html

    1. "en">
    2. "UTF-8">
    3. Title

     3, 中间件处理

    ① 在原Django项目的根路径创建mymiddle.py - 自定义中间件

    1. from django.utils.deprecation import MiddlewareMixin
    2. class CoreMiddle(MiddlewareMixin):
    3. def process_response(self, request, response):
    4. if request.method == 'OPTIONS':
    5. response['Access-Control-Allow-Headers'] = 'Content-Type, authorization' # 如果是 * 就代表全部IP都可以访问
    6. response['Access-Control-Allow-Origin'] = '*'
    7. return response

    ② 在原Django项目的dev.py的中间件中添加自定义中间件

    1. MIDDLEWARE = [
    2. 'django.middleware.security.SecurityMiddleware',
    3. 'django.contrib.sessions.middleware.SessionMiddleware',
    4. 'mymiddle.CoreMiddle', # 这一句
    5. 'django.middleware.common.CommonMiddleware',
    6. # 'django.middleware.csrf.CsrfViewMiddleware',
    7. 'django.contrib.auth.middleware.AuthenticationMiddleware',
    8. 'django.contrib.messages.middleware.MessageMiddleware',
    9. 'django.middleware.clickjacking.XFrameOptionsMiddleware',
    10. ]

    ③ 原Django项目apps/user/views中替换成如下代码

    1. from django.http import JsonResponse
    2. def test(request):
    3. return JsonResponse({'name': 'Darker', 'age': '18'})

    解决跨域问题(第三方)

    后端配置

    ① 后端安装跨域模块

    pip install django-cors-headers
    

    2, 到dev.py中注册

    1. INSTALLED_APPS = (
    2. ...
    3. 'corsheaders'
    4. )

    3  到dev.py中添加中间件

    1. MIDDLEWARE = [
    2. ...
    3. 'corsheaders.middleware.CorsMiddleware',
    4. 'django.middleware.common.CommonMiddleware', # 这个是原本就存在的
    5. ...
    6. ]

    ④ 到dev.py中添加如下代码

    1. CORS_ALLOW_CREDENTIALS = True
    2. CORS_ORIGIN_ALLOW_ALL = True
    3. # CORS_ORIGIN_WHITELIST = (
    4. # 'http://127.0.0.1:8080',
    5. # )
    6. CORS_ALLOWED_ORIGINS_REGEXES=[
    7. r'^http://.*?$',
    8. ]
    9. # CORS_ORIGIN_REGEXES_WHITELIST = (
    10. # r'^http://.*?$',
    11. # )
    12. CORS_ALLOW_METHODS = (
    13. 'DELETE',
    14. 'GET',
    15. 'OPTIONS',
    16. 'PATCH',
    17. 'POST',
    18. 'PUT',
    19. 'VIEW',
    20. )
    21. CORS_ALLOW_HEADERS = (
    22. 'XMLHttpRequest',
    23. 'X_FILENAME',
    24. 'accept-encoding',
    25. 'authorization',
    26. 'content-type',
    27. 'dnt',
    28. 'origin',
    29. 'user-agent',
    30. 'x-csrftoken',
    31. 'x-requested-with',
    32. 'Pragma',
    33. )

     设置dev.pyALLOWED_HOSTS

    ALLOWED_HOSTS = ['*']
    

    后端测试

    (测试 - 后台)到apps/user/views中替换成如下代码

    1. from django.http import JsonResponse
    2. def test(request):
    3. return JsonResponse({'name': 'Darker', 'age': '18'})

    (测试 - 后台)到apps/user/urls中替换成如下代码

    1. from django.urls import path
    2. from user import views
    3. urlpatterns = [
    4. path('test/', views.test),
    5. ]

    启动项目

    python manage.py runserver 127.0.0.1:8000
    

     访问测试

    前端测试

    (测试 - 前台)App.vue 中换成如下代码

    1. <template>
    2. <div id="app">
    3. <router-view/>
    4. {{name}}
    5. div>
    6. template>
    7. <script>
    8. export default {
    9. data () {
    10. return {
    11. name: []
    12. }
    13. },
    14. mounted () {
    15. this.$axios.get(this.$settings.base_url + '/user/test/').then(res => {
    16. this.name = res.data
    17. })
    18. }
    19. }
    20. script>

     启动项目

    npm run serve
    

    解决跨域问题(前端)

    前端App.vue

    1. <template>
    2. <div id="home">
    3. <h1>我是主页h1>
    4. <h2>{{info}}h2>
    5. div>
    6. template>
    7. <script>
    8. export default {
    9. name: 'Home',
    10. data () {
    11. return {
    12. info: []
    13. }
    14. },
    15. mounted () {
    16. this.$axios.get('/moreClassicList?sortId=1&showType=3').then(res => {
    17. console.log(res.data)
    18. })
    19. }
    20. }
    21. script>
    22. <style scoped>
    23. style>

    前端项目根路径 vue.config.js

    1. const webpack = require("webpack");
    2. module.exports = {
    3. configureWebpack: {
    4. plugins: [
    5. new webpack.ProvidePlugin({
    6. $: "jquery",
    7. jQuery: "jquery",
    8. "window.jQuery": "jquery",
    9. "window.$": "jquery",
    10. Popper: ["popper.js", "default"]
    11. })
    12. ]
    13. },
    14. devServer: {
    15. proxy: {
    16. '/ajax': {
    17. target: 'https://m.maoyan.com/',
    18. changeOrigin: true
    19. },
    20. '/user': {
    21. target: 'http://127.0.0.1:8000',
    22. changeOrigin: true
    23. }
    24. }
    25. }
    26. };

     wsgi,uWSGI,uwsgi

    https://www.liuqingzheng.top/article/1/05-CGI,FastCGI,WSGI,uWSGI,uwsgi%E4%B8%80%E6%96%87%E6%90%9E%E6%87%82/

     

  • 相关阅读:
    java 多线程面试题及答案
    spring boot 分布式session实现
    vue3 配置生产和开发 非vite
    mac安装hive 2.3.9
    MySQL学习笔记
    DBCO-PEG-Ciprofloxacin 二苯并环辛炔-聚乙二醇-环丙沙星 DBCO-PEG-环丙沙星
    1024程序员节日:庆祝代码世界的创造者与守护者
    【ARC与MRC的相互兼容 Objective-C语言】
    基于streamlit的成绩展示平台
    AI编程新手快速体验SpringCloud Alibaba 集成AI功能
  • 原文地址:https://blog.csdn.net/weixin_67531112/article/details/127734848