Apache/Nginx:代理POST请求到远程服务器,在本地处理OPTIONS请求

发布于 2024-10-17 03:21:11 字数 1428 浏览 4 评论 0原文

我正在尝试将 Apache 配置为远程服务器的代理,以允许使用 CORS。为了实现这一点,我需要 Apache 响应 2 个 HTTP 动词,如下所示:

  1. OPTIONS: 使用一些简单的 HTTP 标头响应此 CORS“飞行前”请求。我认为这可能是一个简单的 CGI 脚本 (options.pl)。

  2. 帖子: 将所有 POST 请求代理到远程服务器,但添加 Access-Control-Allow-Origin "*" 标头以允许跨域请求发生。

我可以独立实现这两个要求,但我无法配置 Apache 来同时满足这两个要求。问题是,当配置 ProxyPass 和 ProxyPassReverse 时,OPTIONS 请求不再命中 CGI 脚本,它们会被代理到远程服务器。

我当前的配置如下。如果可能的话,我想使用纯 Web 服务器解决方案(例如 Apache/Nginx)来解决这个问题(而不是运行一些应用程序代码)。

<VirtualHost *:80>

    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/

    DocumentRoot /var/www

    <Location "/">

        # Disallow all verbs except OPTIONS and POST
        order deny,allow
        deny from all

        # OPTIONS should be handled by a local CGI script
        <Limit OPTIONS>
            allow from all
            Script OPTIONS /cgi-bin/options.pl
        </Limit>

        # POST requests are proxied to a remote server
        <Limit POST>
            allow from all
            ProxyPass http://somewhere-else/
            ProxyPassReverse http://somewhere-else/
            Header add Access-Control-Allow-Origin "*"
        </Limit>

    </Location>
</VirtualHost>

I am trying to configure Apache to act as a proxy to a remote server, to allow cross-domain AJAX using CORS. To achieve this, I need Apache to respond to 2 HTTP verbs, like so:

  1. OPTIONS:
    Respond to this CORS 'pre-flight' request with some simple HTTP headers. I had in mind that this could be a simple CGI script (options.pl).

  2. POST:
    Proxy all POST requests to the remote server, but add the Access-Control-Allow-Origin "*" header to allow the cross-domain request to happen.

I can achieve both of these requirements independently, but I cannot configure Apache to do both. The problem is that when the ProxyPass and ProxyPassReverse is configured, the OPTIONS requests no longer hit the CGI script, they are proxied to the remote server.

My current config is below. I'd like to solve this with a pure web-server solution e.g. Apache/Nginx (rather than running some application code), if possible.

<VirtualHost *:80>

    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/

    DocumentRoot /var/www

    <Location "/">

        # Disallow all verbs except OPTIONS and POST
        order deny,allow
        deny from all

        # OPTIONS should be handled by a local CGI script
        <Limit OPTIONS>
            allow from all
            Script OPTIONS /cgi-bin/options.pl
        </Limit>

        # POST requests are proxied to a remote server
        <Limit POST>
            allow from all
            ProxyPass http://somewhere-else/
            ProxyPassReverse http://somewhere-else/
            Header add Access-Control-Allow-Origin "*"
        </Limit>

    </Location>
</VirtualHost>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

<逆流佳人身旁 2024-10-24 03:21:11

下面是我使用 Nginx 解决这个问题的方法。请注意,我正在使用 Headers More 模块,这需要我 从源代码编译 Nginx

location / {

    if ($request_method = 'OPTIONS') {
        more_set_headers 'Access-Control-Allow-Origin: *';
        more_set_headers 'Access-Control-Allow-Methods: POST, OPTIONS';
        more_set_headers 'Access-Control-Max-Age: 1728000';
        more_set_headers 'Content-Type: text/plain; charset=UTF-8';

        return 200;
    }

    if ($request_method = 'POST') {
        more_set_headers 'Access-Control-Allow-Origin: *';
        proxy_pass http://somewhere-else;
    }
}

Here's how I've solved it using Nginx. Note that I am using the Headers More module which required me to compile Nginx from source.

location / {

    if ($request_method = 'OPTIONS') {
        more_set_headers 'Access-Control-Allow-Origin: *';
        more_set_headers 'Access-Control-Allow-Methods: POST, OPTIONS';
        more_set_headers 'Access-Control-Max-Age: 1728000';
        more_set_headers 'Content-Type: text/plain; charset=UTF-8';

        return 200;
    }

    if ($request_method = 'POST') {
        more_set_headers 'Access-Control-Allow-Origin: *';
        proxy_pass http://somewhere-else;
    }
}
帥小哥 2024-10-24 03:21:11

您现在可以使用我的 nginx_cross_origin_module 了。它支持完整的 CORS 功能: https://github.com/yaoweibin/nginx_cross_origin_module

示例:

http {

    cors on;
    cors_max_age     3600;
    cors_origin_list unbounded;
    cors_method_list GET HEAD PUT POST;
    cors_header_list unbounded;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }
    }
} 

You can use my nginx_cross_origin_module now. It supports the full CORS feature: https://github.com/yaoweibin/nginx_cross_origin_module

Example:

http {

    cors on;
    cors_max_age     3600;
    cors_origin_list unbounded;
    cors_method_list GET HEAD PUT POST;
    cors_header_list unbounded;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }
    }
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文