重定向包括标题

发布于 2025-01-25 20:05:25 字数 1840 浏览 2 评论 0原文

问题:我的HTML/JavaScript应用程序会收到重定向的CORS错误。

目标:将Apache配置为仅在特定重定向期间包括HTTP标头。

重要说明:此HTML从本地加载的文件中,而不是从Web服务器提供的页面中运行。

代码:

<body>
  <div id="response">Loading page ...</div>

<script type="text/javascript">
  async function get_response() {
      let url = 'https://example.com/endpoint'

      fetch(url, {
        redirect: "follow"
      })
        .then(response => response.text())
        .then(data => {
          document.getElementById('response').innerHTML = data;
        })
        .catch(error => {
          console.log(error);
        });
  }

  get_response();
</script>
</body>

代码描述:

上面代码从URL获取数据并将其显示在浏览器中。但是,该网站发送302重定向(按设计)。重定向会导致CORS错误。

CORS错误:

访问'https://example.com/Endpoint'来自原始'null'的获取 CORS政策已阻止:没有“访问控制 - 允许孔” 标题存在于请求的资源上。如果不透明的反应 满足您的需求,将请求的模式设置为“无现体”以获取 禁用CORS的资源。

生成重定向的Apache配置:

RewriteEngine on
RewriteRule ^(/endpoint)$ /system/endpoint.php? [END,NE,R=302]

可能无法接受的解决方法:

  1. 配置Apache在重写之前发送CORS标头:

    标题始终设置访问控制-Allow-Origin“*”

这不是一个好的解决方案,因为我不想将此标头发送给所有URL,仅此一个重定向。其他页面确实设置了此标头,并且当Chrome接收到具有相同值的几个访问控制标题时,会生成错误而不是接受标题。注意:AFAIK 标题总是设置必须包括3xx响应的标头。

  1. 修改应用程序以使用重定向的URL而不是重定向的URL。

由于最终URL是可配置的,这将无法使用,并且目的是在后端路由更改时不要修改应用程序。

其他解决方法:

我通过编写这个问题并通过问题思考来意识到,我的重写正在生成一个对所有情况所必需的重定向。对于在同一域中的重定向,URL重写就足够了。为了重定向到我需要做的子域,重写URL是不够的。

对于相同的域URL更改,这将有效:

RewriteRule ^(/endpoint)$ /system/endpoint.php? [L]

对于真正的重定向,我需要一种有条件地包含CORS标头的方法。

Problem: My HTML/JavaScript app receives a CORS error processing a redirect.

Objective: Configure Apache to include an HTTP header only during a specific redirect.

Important note: This HTML runs in a browser from a locally loaded file and not from a page served by a web server.

The Code:

<body>
  <div id="response">Loading page ...</div>

<script type="text/javascript">
  async function get_response() {
      let url = 'https://example.com/endpoint'

      fetch(url, {
        redirect: "follow"
      })
        .then(response => response.text())
        .then(data => {
          document.getElementById('response').innerHTML = data;
        })
        .catch(error => {
          console.log(error);
        });
  }

  get_response();
</script>
</body>

Code Description:

The above code fetches data from a URL and displays it in the browser. However, the website sends a 302 redirect (by design). The redirect causes a CORS error.

CORS Error:

Access to fetch at 'https://example.com/endpoint' from origin 'null'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin'
header is present on the requested resource. If an opaque response
serves your needs, set the request's mode to 'no-cors' to fetch the
resource with CORS disabled.

The Apache configuration that generates the redirect:

RewriteEngine on
RewriteRule ^(/endpoint)$ /system/endpoint.php? [END,NE,R=302]

Possible workarounds that are not acceptable:

  1. Configure Apache to send a CORS header before the RewriteRule:

    Header always set Access-Control-Allow-Origin "*"

This is not a good solution because I do not want to send this header for all URLs only this one redirect. Other pages do set this header and when Chrome receives several Access-Control-Allow-Origin headers with the same value, an error is generated instead of accepting the headers. Note: AFAIK header always set is required to include the header for 3xx responses.

  1. Modify the application to use the redirected URL instead of a URL that redirects.

This will not work as the final URL is configurable and the objective is to not modify the application when the backend routes change.

Other Workarounds:

I realized by writing this question and thinking through the problem, that my RewriteRule is generating a redirect that is not necessary for all situations. For a redirect within the same domain, a URL rewrite is enough. For redirecting to subdomains, which I need to do, rewriting the URL is not enough.

For the same domain URL change, this will work:

RewriteRule ^(/endpoint)$ /system/endpoint.php? [L]

For a true redirect, I need a method to conditionally include the CORS header.

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

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

发布评论

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

评论(1

小巷里的女流氓 2025-02-01 20:05:25

该解决方案是将Apache &lt; IF组合使用服务器变量request_uri

<If "%{REQUEST_URI} == '/endpoint'">
Header always set Access-Control-Allow-Origin "*"
</If>

RewriteEngine on
RewriteRule ^(/endpoint)$ https://example2.com/system/endpoint? [END,NE,R=302]

还必须配置新的端点以用access> access-control--允许原素标头。

<指令

apache Server变量

访问control-allow-origin“*”响应,我的解决方案击败了CORS的目的,该目的是防止未经授权的资源共享。该解决方案将在安全审核中触发警告或违规行为。由于我只是在后端中的特定路线,而不是所有路线,因此可以对此进行解释/记录。

当我在堆栈溢出和Internet上研究此问题时,每个答案/文章都建议返回“访问控制 - 允许 - 原始”“*”标头。那几乎是时间的错误解决方案。安全控制的目的是执行它,而不是绕过它。

The solution is to combine the Apache <If> directive with the server variable REQUEST_URI:

<If "%{REQUEST_URI} == '/endpoint'">
Header always set Access-Control-Allow-Origin "*"
</If>

RewriteEngine on
RewriteRule ^(/endpoint)$ https://example2.com/system/endpoint? [END,NE,R=302]

The new endpoint must also be configured to respond with the Access-Control-Allow-Origin header.

Apache <If> Directive

Apache Server Variables

[Update]

By responding with Access-Control-Allow-Origin "*", my solution defeats the purpose of CORS which is to prevent unauthorized resource sharing. This solution will trigger a warning or a violation in a security audit. Since I am only wildcarding specific routes in the backend and not all routes, this can be explained/documented.

When I researched this issue on Stack Overflow and on the Internet, each answer/article recommended returning the `Access-Control-Allow-Origin "*" header. That is the wrong solution almost of the time. The purpose of a security control is to enforce it, and not to bypass it.

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