返回 304 Not Modified with ServiceStack 时防止不需要的标头

Posted

技术标签:

【中文标题】返回 304 Not Modified with ServiceStack 时防止不需要的标头【英文标题】:Prevent unwanted headers when returning 304 Not Modified with ServiceStack 【发布时间】:2012-08-04 13:22:56 【问题描述】:

使用 ServiceStack,我只想返回 304 Not Modified

HTTP/1.1 304 Not Modified

但是 ServiceStack 添加了许多其他不需要的(返回带有 304 代码的 HttpResult)标头:

HTTP/1.1 304 Not Modified
Content-Length: 0
Content-Type: application/json
Server: Microsoft-HTTPAPI/2.0
X-Powered-By: ServiceStack/3.94 Win32NT/.NET
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type
Date: Tue, 07 Aug 2012 13:39:19 GMT

如何防止其他标头被输出?我用HttpResult 尝试了各种方法,注册了一个虚拟内容类型过滤器,但顾名思义,它只控制内容,而不是标题,或者here 列出的其他内容。我还尝试使用 IStreamWriter 和 IHasOptions 实现我自己的 IHttpResult 衍生产品,结果相同:ServiceStack 添加了不需要的标头。

谢谢

更新

能够使用以下命令删除content-type,但仍然存在一些标头,即content-lengthserverdate

    public override object OnGet(FaultTypes request)
    
      var result = new HttpResult
      
       StatusCode = HttpStatusCode.NotModified,
       StatusDescription = "Not Modified", // Otherwise NotModified written!
      ;

      // The following are hacks to remove as much HTTP headers as possible
      result.ResponseFilter = new NotModifiedContentTypeWriter();
      // Removes the content-type header
      base.Request.ResponseContentType = string.Empty;

      return result;
    

class NotModifiedContentTypeWriter : ServiceStack.ServiceHost.IContentTypeWriter

  ServiceStack.ServiceHost.ResponseSerializerDelegate ServiceStack.ServiceHost.IContentTypeWriter.GetResponseSerializer(string contentType)
  
    return ResponseSerializerDelegate;
  

  void ServiceStack.ServiceHost.IContentTypeWriter.SerializeToResponse(ServiceStack.ServiceHost.IRequestContext requestContext, object response, ServiceStack.ServiceHost.IHttpResponse httpRes)
  
  

  void ServiceStack.ServiceHost.IContentTypeWriter.SerializeToStream(ServiceStack.ServiceHost.IRequestContext requestContext, object response, System.IO.Stream toStream)
  
  

  string ServiceStack.ServiceHost.IContentTypeWriter.SerializeToString(ServiceStack.ServiceHost.IRequestContext requestContext, object response)
  
    return string.Empty;
  

  public void ResponseSerializerDelegate(ServiceStack.ServiceHost.IRequestContext requestContext, object dto, ServiceStack.ServiceHost.IHttpResponse httpRes)
  
  

【问题讨论】:

【参考方案1】:

实际上你可以在你的 API 中做这样的事情

base.Response.StatusCode = (int) HttpStatusCode.NotModified;
base.Response.EndHttpRequestWithNoContent();
return new HttpResult();

不会返回 ContentType、ContentLength 等

【讨论】:

【参考方案2】:

ServiceStack 发出的唯一标头是在EndpointHostConfig.GlobalResponseHeaders 中注册的标头。

如果您不希望它们发出,请将它们删除,例如:

SetConfig(new EndpointHostConfig  
    GlobalResponseHeaders = new Dictionary<string,string>()
);

您可以使用 HttpResult 临时添加它们,例如:

return new HttpResult(dto) 
    Headers = 
        "Access-Control-Allow-Origin", "*" ,
        "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"  
        "Access-Control-Allow-Headers", "Content-Type" , 
;

这两个选项在servicestack REST API and CORS进行了更详细的解释

【讨论】:

感谢您的回答,但这只会删除 CORS,而不是其他的。我还有 HTTP/1.1 304 Not Modified Content-Length: 0 Content-Type: application/json Expires: Thu, 16 Aug 2012 16:20:25 GMT Server: Microsoft-HTTPAPI/2.0 Date: Thu, 16 Aug 2012 16:格林威治标准时间 20:24 发出的标头不在GlobalResponseHeaders 中或在每个服务的基础上添加自己的HttpResult 不是来自ServiceStack。 IIS / ASP.NET 可以选择添加自己的标头。 不使用 IIS/ASP.Net,只是控制台应用测试。似乎是从 JSON 序列化程序和其他添加的。我该如何控制这些? 没有从任何序列化程序中添加。您确定要设置GlobalResponseHeaders = new Dictionary&lt;string,string&gt;() 吗?这将删除 ServiceStack 标头。不知道怎么去掉HttpListener添加的ServerHTTP头。 是的,GlobalResponseHeaders 是空字典。似乎内容类型和长度是由 JSON 序列化程序自动添加的,但无法控制它们......

以上是关于返回 304 Not Modified with ServiceStack 时防止不需要的标头的主要内容,如果未能解决你的问题,请参考以下文章

304 Not Modified

防止Tomcat中的304 NOT MODIFIED响应

nginx 304 not modified 怎样解决

如何防止nginx中的“304 Not Modified”?

200 OK (from cache) 与 304 Not Modified

If-None-Match 有效时 304 Not Modified