zoukankan      html  css  js  c++  java
  • 跨域问题

    跨域问题

    一、浏览器的同源策略

    同源策略,浏览器拒绝不是当前域返回的数据。
    	比如: 当你从其他网站向百度发送请求的时候,百度在执行完后会返回数据给你,但是该返回的数据因为不是在同一个域下,所以浏览器会给你拒绝掉该数据
    
    • 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现
    • 请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同.
    • 比如:我在本地上的域名是127.0.0.1:8000,请求另外一个域名:127.0.0.1:8001一段数据
    • 浏览器上就会报错,这就是同源策略的保护,如果浏览器对javascript没有同源策略的保护,那么一些重要的机密网站将会很危险
    已拦截跨源请求:同源策略禁止读取位于 http://127.0.0.1:8001/SendAjax/ 的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')。
    

    但是注意,当项目中的访问已经发生了,说明是浏览器对非同源请求返回的结果做了拦截

    二、CORS(跨域资源共享)简介

    • CORS(Cross-Origin Resource Sharing)跨域资源共享
    • CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
    • 整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
    • 因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

    三、CORS基本流程

    • 浏览器将CORS请求分成两类:简单请求(simple request)非简单请求(not-so-simple request)。
    • 浏览器发出CORS简单请求只需要在头信息之中增加一个Origin字段。
    • 浏览器发出CORS非简单请求会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

    四、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
    

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

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

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

    --简单请求:
    	一次请求
    --非简单请求:
    	两次请求,在发送数据之前会先发一次请求用于做“预检”(options),只有“预检”通过后才再发送一次请求用于数据传输。
    * 关于“预检”
    - 请求方式:OPTIONS
    - “预检”其实做检查,检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息
    - 如何“预检”
         => 如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过
            Access-Control-Request-Method
         => 如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过
            Access-Control-Request-Headers
    
    

    总结:

    支持跨域,简单请求

    • 服务器设置响应头:Access-Control-Allow-Origin = '域名' 或 '*'

    支持跨域,复杂请求

    由于复杂请求时,首先会发送“预检”请求,如果“预检”成功,则发送真实数据。

    • “预检”请求时,允许请求方式则需服务器设置响应头:Access-Control-Request-Method
    • “预检”请求时,允许请求头则需服务器设置响应头:Access-Control-Request-Headers

    五、Django项目中支持CORS

    在返回的结果中加入允许信息(简单请求)

    def test(request):
        import json
        obj=HttpResponse(json.dumps({'name':'lqz'}))
        # obj['Access-Control-Allow-Origin']='*'  这样加入不安全
        obj['Access-Control-Allow-Origin']='http://127.0.0.1:8004'
        return obj
    

    放到中间件中处理简单和复杂请求:

    rom django.utils.deprecation import MiddlewareMixin
    class CorsMiddleWare(MiddlewareMixin):
        def process_response(self,request,response):
            if request.method=="OPTIONS":
                #可以加*
                response["Access-Control-Allow-Headers"]="Content-Type"
            response["Access-Control-Allow-Origin"] = "http://localhost:8080"
            return response
    
    注:实际项目中的话,一般用别人写的CORS 来解决跨域问题
    • cors-header 第三方模块,导入模块在settings.py 里面做一下配置
  • 相关阅读:
    Spring Cloud Hystrix Dashboard的使用 5.1.3
    Spring Cloud Hystrix 服务容错保护 5.1
    Spring Cloud Ribbon 客户端负载均衡 4.3
    Spring Cloud 如何实现服务间的调用 4.2.3
    hadoop3.1集成yarn ha
    hadoop3.1 hdfs的api使用
    hadoop3.1 ha高可用部署
    hadoop3.1 分布式集群部署
    hadoop3.1伪分布式部署
    KVM(八)使用 libvirt 迁移 QEMU/KVM 虚机和 Nova 虚机
  • 原文地址:https://www.cnblogs.com/qianzhengkai/p/11153190.html
Copyright © 2011-2022 走看看