浏览器无法正确识别内容类型标头
我的浏览器出现问题,无法识别我在响应中发送的内容类型,并尝试下载文件而不是显示它。
我有一个用 ASP.Net 编写的通用处理程序(名为 SPARQL.ashx),它执行一些工作并生成一个具有两种可能类型的对象。 它获取 SPARQLResultSet 或 Graph,然后在使用适当的 Save 方法将内容发送给用户之前设置适当的内容类型。 代码片段如下:
//Execute the Query
Object result = store.ExecuteQuery(sparqlquery);
if (result is SPARQLResultSet)
{
//Return as SPARQL Results XML Format
context.Response.ContentType = MIMETypesHelper.SPARQL[0];
SPARQLResultSet resultset = (SPARQLResultSet)result;
resultset.Save(new StreamWriter(context.Response.OutputStream));
}
else if (result is Graph)
{
//Return as Turtle
context.Response.ContentType = MIMETypesHelper.Turtle[0];
Graph g = (Graph)result;
TurtleWriter ttlwriter = new TurtleWriter();
ttlwriter.PrettyPrintMode = true;
ttlwriter.Save(g, new StreamWriter(context.Response.OutputStream));
}
我的问题是,我的浏览器经常会提示下载结果而不是显示结果,尽管一种格式是基于 XML 的,另一种格式是基于纯文本的,因此两者都应该可以在任何现代浏览器中显示。
行为因浏览器而异,有些浏览器会提示下载,无论结果格式如何,有些会提示其中一种,但不会提示另一种。
我是否可能需要以某种方式配置 IIS 以确保发送正确的 MIME 类型。 作为记录,我在 IIS 中注册了官方文件扩展名和 MIME 类型。 或者这是因为我使用通用处理程序而导致的问题? 或者有人有任何其他想法为什么会发生这种情况?
编辑
为了清晰起见,添加了 MIMETypesHelper 类中的代码
/// <summary>
/// Helper Class containing arrays of MIME Types for the various RDF Concrete Syntaxes
/// </summary>
/// <remarks>The first type in each array is the canonical type that should be used</remarks>
public class MIMETypesHelper
{
/// <summary>
/// MIME Types for Turtle
/// </summary>
public static string[] Turtle = { "text/turtle", "application/x-turtle", "application/turtle" };
/// <summary>
/// MIME Types for RDF/XML
/// </summary>
public static string[] RDFXML = { "application/rdf+xml" };
/// <summary>
/// MIME Types for Notation 3
/// </summary>
public static string[] Notation3 = { "text/n3", "text/rdf+n3" };
/// <summary>
/// MIME Types for NTriples
/// </summary>
public static string[] NTriples = { "text/plain" };
/// <summary>
/// MIME Types for SPARQL Result Sets
/// </summary>
public static string[] SPARQL = { "application/sparql-results+xml" };
///etc.
}
I have an issue with my browser failing to recognise the content types I am sending in my responses and trying to download the file instead of displaying it.
I have a generic handler (named SPARQL.ashx) written in ASP.Net which does some work and produces an object which is of two possible types. Either it gets a SPARQLResultSet or a Graph and it then sets the appropriate content type before using the appropriate Save method to send the content to the user. Code fragment is below:
//Execute the Query
Object result = store.ExecuteQuery(sparqlquery);
if (result is SPARQLResultSet)
{
//Return as SPARQL Results XML Format
context.Response.ContentType = MIMETypesHelper.SPARQL[0];
SPARQLResultSet resultset = (SPARQLResultSet)result;
resultset.Save(new StreamWriter(context.Response.OutputStream));
}
else if (result is Graph)
{
//Return as Turtle
context.Response.ContentType = MIMETypesHelper.Turtle[0];
Graph g = (Graph)result;
TurtleWriter ttlwriter = new TurtleWriter();
ttlwriter.PrettyPrintMode = true;
ttlwriter.Save(g, new StreamWriter(context.Response.OutputStream));
}
My issue is that my browser will often prompt to download the results rather than displaying them despite the fact that one format is XML based and the other plain text based and so should both be displayable in any modern browser.
Behaviour varies from browser to browser and some will prompt for download regardless of result format and some will for one but not the other.
Am I likely to need to configure IIS somehow to ensure the correct MIME types are sent. For the record I have the official file extensions and MIME types registered in IIS. Or is this an issue with the fact that I'm using a Generic Handler? Or does anyone have any other ideas why this might be happening?
Edit
Added code from MIMETypesHelper class for clarity
/// <summary>
/// Helper Class containing arrays of MIME Types for the various RDF Concrete Syntaxes
/// </summary>
/// <remarks>The first type in each array is the canonical type that should be used</remarks>
public class MIMETypesHelper
{
/// <summary>
/// MIME Types for Turtle
/// </summary>
public static string[] Turtle = { "text/turtle", "application/x-turtle", "application/turtle" };
/// <summary>
/// MIME Types for RDF/XML
/// </summary>
public static string[] RDFXML = { "application/rdf+xml" };
/// <summary>
/// MIME Types for Notation 3
/// </summary>
public static string[] Notation3 = { "text/n3", "text/rdf+n3" };
/// <summary>
/// MIME Types for NTriples
/// </summary>
public static string[] NTriples = { "text/plain" };
/// <summary>
/// MIME Types for SPARQL Result Sets
/// </summary>
public static string[] SPARQL = { "application/sparql-results+xml" };
///etc.
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Content-Dispostion 标头设置为什么? 应将其设置为“内联”。 您可能想尝试手动设置它以查看行为是否发生变化。
What's the Content-Dispostion header set to? It should be set to "inline". You might want to try setting it manually to see if the behavior changes.
在我们的 RDF 存储引擎系列中,我们通过进行内容协商来解决这个问题。
也就是说,我们检查 HTTP 请求标头中的 Accept 行,并相应地调整我们的行为。 如果 Accept 行明确提到任何 RDF 风格,或者 SPARQL 结果 MIME 类型,那么我们会发回适当的 Content-type 和关联的响应。 根据我们的经验,这可以很好地服务于专用的 SPARQL 客户端、手动代码和各种 RDF“浏览器”工具。
但对于典型的 Web 浏览器,Accept 行仅列出 HTML 和一些图像格式,并且我们的 HTTP 守护程序将 Content-type 设置为 text/plain(或者对于空白 SPARQL 查询,text/html,响应正文为 Web 最后,如果 Accept 标头完全丢失,
我们知道这是一个非常幼稚的软件,很可能是某人的 Perl 脚本或其他东西,我们有一个特殊的情况来在针对存储引擎进行开发时,让人们的生活变得更轻松。
In our family of RDF storage engines we attack this problem by doing content negotiation.
That is, we check the Accept line in the HTTP request headers, and adjust our behaviour accordingly. If the Accept line mentions any RDF flavours, or the SPARQL results MIME type explicitly, then we send back the appropriate Content-type and associated response. This serves dedicated SPARQL clients, hand-rolled code and various RDF "browser" tools very well in our experience.
But for a typical web browser the Accept line just lists HTML and a few image formats, and our HTTP daemon sets the Content-type to text/plain (or for a blank SPARQL query, text/html, with the response body being a web page with a form for writing manual queries from a web browser for testing)
Finally if the Accept header is missing altogether we know it's a very naive piece of software, most likely someone's Perl script or something, and we have a special case for that to make people's lives easier when developing against the storage engine.
终于找到了问题的根源,似乎您必须在响应上调用 Clear() 并使用缓冲,否则内容类型标头不会按预期发送:
例如。
Finally found the source of the issue, seems you have to call Clear() on the response and use Buffering or the Content Type header doesn't get sent as expected:
eg.
从您的代码来看,您似乎依赖于 rdf 库中的 mimetypes(您没有说出是哪一个)。 当诸如 firefox / IE 之类的浏览器(你没有说你正在使用哪个)看到 mime 类型
application/
SOMETHING 时,它通常会提供保存而不是查看它。RDF/XML 的 mime 类型是
application/rdf+xml
(我知道,因为我编写了规范),这将导致另存为方法。 Turtle 的 mime 类型(我在 Turtle note 中创建的)不是已注册,但建议使用text/turtle
,它应该显示良好。From your code it looks like you are relying on the mimetypes in the rdf library (you don't say which one). When a browser such as firefox / IE (you don't say which you are using) sees a mime type
application/
SOMETHING it typically offers to save it rather than view it.The mime type for RDF/XML is
application/rdf+xml
(I know, since I wrote the spec) and that will cause the save-as approach. The mime type for Turtle (which I created in Turtle note) is not registered but was suggested to betext/turtle
which should display fine.