用于 Ajax 请求的金字塔 CORS

问题描述 投票:0回答:5

是否可以自动将

Access-Control-Allow-Origin
标头添加到 Pyramid 中由 ajax 请求(带有标头
X-Requested-With
)发起的所有响应中?

python cors pyramid
5个回答
17
投票

有几种方法可以做到这一点:1)像 drnextgis 所示的自定义请求工厂、NewRequest 事件处理程序或补间。补间几乎肯定不是执行此操作的正确方法,因此我不会展示这一点。这是事件处理程序版本:

def add_cors_headers_response_callback(event):
    def cors_headers(request, response):
        response.headers.update({
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'POST,GET,DELETE,PUT,OPTIONS',
        'Access-Control-Allow-Headers': 'Origin, Content-Type, Accept, Authorization',
        'Access-Control-Allow-Credentials': 'true',
        'Access-Control-Max-Age': '1728000',
        })
    event.request.add_response_callback(cors_headers)

from pyramid.events import NewRequest
config.add_subscriber(add_cors_headers_response_callback, NewRequest)

10
投票

我已经使用

set_request_factory
解决了问题:

from pyramid.request import Request
from pyramid.request import Response

def request_factory(environ):
    request = Request(environ)
    if request.is_xhr:
        request.response = Response()
        request.response.headerlist = []
        request.response.headerlist.extend(
            (
                ('Access-Control-Allow-Origin', '*'),
                ('Content-Type', 'application/json')
            )
        )
    return request

config.set_request_factory(request_factory)

2
投票

我在 Pyramid 应用程序中针对 AJAX 请求启用 CORS(跨源资源共享)时遇到了类似的问题。我通过设置一种机制来自动将 CORS 标头添加到所有响应中来解决这个问题。这是完整的解决方案:

  1. 创建 CORS 预检谓词: 此谓词通过查找特定请求标头来检查 CORS 预检 (OPTIONS) 请求。

    class CorsPreflightPredicate(object):
        def __init__(self, val, config):
            self.val = val
    
        def text(self):
            return 'cors_preflight = %s' % bool(self.val)
    
        phash = text
    
        def __call__(self, context, request):
            return (request.method == 'OPTIONS' and
                    'HTTP_ORIGIN' in request.headers.environ and
                    'HTTP_ACCESS_CONTROL_REQUEST_METHOD' in request.headers.environ)
    
  2. 为预检请求添加路线和视图: 此路由捕获所有 URL 并处理它们(如果它们是 CORS 预检请求)。

    def add_cors_preflight_handler(config):
        config.add_route('cors-options-preflight', '/{catch_all:.*}', cors_preflight=True)
        config.add_view(cors_options_view, route_name='cors-options-preflight', permission=NO_PERMISSION_REQUIRED)
    
    def cors_options_view(context, request):
        response = request.response
        if 'HTTP_ACCESS_CONTROL_REQUEST_HEADERS' in request.headers.environ:
            response.headers.update({...})  # Add necessary CORS headers here
        return response
    
  3. 添加响应回调: 该回调将 CORS 标头添加到跨源请求的所有响应中。

    def add_cors_to_response(event):
        request = event.request
        response = event.response
        if 'HTTP_ORIGIN' in request.headers.environ:
            response.headers.update({...})  # Add necessary CORS headers here
    
  4. 在应用程序中集成 CORS 处理: 将 CORS 设置包含在您的 Pyramid

    Configurator
    对象中。

    def includeme(config):
        config.add_directive('add_cors_preflight_handler', add_cors_preflight_handler)
        config.add_route_predicate('cors_preflight', CorsPreflightPredicate)
        config.add_subscriber(add_cors_to_response, 'pyramid.events.NewResponse')
    
    # In your Pyramid configurator setup
    config.include('path.to.cors_module')
    config.add_cors_preflight_handler()
    

此方法有效地将 CORS 标头添加到 AJAX 请求的响应中,并确保符合 CORS 预检要求。请记住根据您的要求将

{...}
替换为实际的 CORS 标头。例如,以下内容对我有用:

{
                'Access-Control-Allow-Origin': '*',
                'Access-Control-Expose-Headers': 'Content-Type,Date,Content-Length,Authorization,X-Request-ID',
                'Access-Control-Allow-Methods': 'POST,GET,DELETE,PUT,OPTIONS',
                'Access-Control-Allow-Headers': 'Origin, Content-Type, Accept, Accept-Language, Authorization ,X-Request-ID',
                'Access-Control-Allow-Credentials': 'true',
                'Access-Control-Max-Age': '1728000',
            }

1
投票

我可以使用 Ajax 将文件从一台服务器发送到另一台服务器:

import uuid

from pyramid.view import view_config

from pyramid.response import Response


class FManager:

    def __init__(self, request):
        self.request = request

    @view_config(route_name='f_manager', request_method='POST', renderer='json')
    def post(self):
        file_ = self.request.POST.items()
        content_type = str(file_[0][1].type).split('/')
        file_[0][1].filename = str(uuid.uuid4()) + '.' + content_type[1]
        file_id = self.request.storage.save(file_[0][1])

        response = Response(body="{'data':'success'}")
        response.headers.update({
            'Access-Control-Allow-Origin': '*',
        })

        return response

1
投票

这是另一种解决方案:

from pyramid.events import NewResponse, subscriber

@subscriber(NewResponse)
def add_cors_headers(event):
    if event.request.is_xhr:
        event.response.headers.update({
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'GET',
        })
© www.soinside.com 2019 - 2024. All rights reserved.