我应该在OPTIONS请求之后的实际请求中向任何非允许的来源发送任何Access-Control-Allow-Origin标头吗?

时间:2017-09-07 02:36:22

标签: cors cross-domain preflight

我对它是如何工作有一个大概的了解。我将返回相同的" ORIGIN"如果请求"起源"标头有效(允许)

但我不知道:

  1. 对于OPTIONS请求之后的实际请求,我是否需要包含我返回到客户端的完全相同的Access-Control-Allow-Origin标头以进行预检请求?如果有一个" ORIGIN"服务器代码只需要这样做。标题存在于实际请求中? (在下面的代码中,我没有检查请求是OPTIONS / preflight请求还是实际请求,我假设相同的代码可以同时适用于两者并且没有任何损害。)
  2. (更多详细信息,因为"响应中的' Access-Control-Allow-Origin'标头的值不能是通配符' *'当请求的凭据模式是' include',"所以我需要请求中的ORIGIN值重新​​放回到响应中。

    1. 如果不允许使用ORIGIN,我应该返回什么?

      根本不包括Access-Control-Allow-Origin标题?
      或setHeader(" Access-Control-Allow-Origin",""), 或setHeader(" Access-Control-Allow-Origin"," null")?

    2. public class CORSResponseFilter implements ContainerResponseFilter {
      
      @Override
      public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
          MultivaluedMap<String, Object> headers = responseContext.getHeaders();
      
          String origin = requestContext.getHeaderString("Origin"); 
      
      
      String origin = requestContext.getHeaderString("Origin");
      
          URL originUrl = null;
          try {
              if (StringUtils.hasText(origin)) {
                  originUrl = new URL(origin);
      
                  Pattern hostAllowedPattern = Pattern.compile("(.+\\.)*mydomain\\.com", Pattern.CASE_INSENSITIVE);
      
                  if (hostAllowedPattern.matcher(originUrl.getHost()).matches()) {
                      headers.add("Access-Control-Allow-Origin", origin);
                  } else {
                      headers.add("Access-Control-Allow-Origin", "");
                  }
                  headers.add("Vary", "Origin");
              }
      
              headers.add("Access-Control-Allow-Credentials", "true");
              headers.add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
              headers.add("Access-Control-Allow-Headers",
      

1 个答案:

答案 0 :(得分:5)

  

对于OPTIONS请求之后的实际请求,我是否需要包含我返回到客户端的完全相同的Access-Control-Allow-Origin标头以进行预检请求?

是的 - 也就是说,如果您要发回实际原始值而不是&#34; *&#34;通配符,该原始值是导致OPTIONS请求成功的原因。因为如果发回不同于OPTIONS成功的非通配符原点值,则会导致浏览器阻止客户端代码访问响应(因为实际原点不匹配)。 / p>

  

如果有一个&#34; ORIGIN&#34;服务器代码只需要这样做?标题出现在实际请求中?

是的,因为当在浏览器中运行的前端JavaScript代码使用XHR或Fetch API或来自某个JavaScript库的Ajax方法来发出跨源请求时,浏览器总是会在请求中添加Origin标头。 Access-Control-Allow-Origin仅供浏览器使用。

因此,将Access-Control-Allow-Origin发送回未在请求中发送Origin的非浏览器工具是没有意义的 - 在这种情况下,它只是您发送的浪费的字节。< / p>

当然有人可以使用curl或任何非浏览器工具向服务器发送请求,并手动向请求添加Origin标头。但是没关系 - 在这种情况下,他们得到的响应与您发送给浏览器的响应相同。所以这实际上对测试很有帮助。

  

如果不允许使用ORIGIN,我应该返回什么?   根本不包括Access-Control-Allow-Origin标题?

是。对于这些情况,根本不要发回Access-Control-Allow-Origin响应标头。这是缺少标头的语义:如果服务器没有发送Access-Control-Allow-Origin响应头,这意味着服务器没有选择允许来自运行浏览器的前端代码的跨源请求,因此默认的同源策略适用。

也就是说,通过不发送Access-Control-Allow-Origin响应标头,服务器告诉浏览器:“请使用默认的同源策略,禁止从所有前端JavaScript代码访问此响应发送此请求的来源。“

  

或setHeader(&#34; Access-Control-Allow-Origin&#34;,&#34;&#34;),

不,没有必要像这样发回空值。这并不意味着什么特别的。

  

或setHeader(&#34; Access-Control-Allow-Origin&#34;,&#34; null&#34;)?

绝对不要那样做。在许多情况下,浏览器会发送值为Origin的{​​{1}}标头,除非您有意允许null的所有请求访问服务器的响应,否则请勿执行此操作这一点。

有关详细信息,请参阅 当浏览器必须在内部将原点设置为<{1}} 的值时,的答案的一部分When does Firefox set the Origin header to null in POST requests?