手机版

静态文件的详细说明 网络核心中间件

时间:2021-08-30 来源:互联网 编辑:宝哥软件园 浏览:

一.导言

静态文件,如HTML、CSS、图片和JavaScript,将由ASP.NET核心应用程序直接提供给客户端。

在介绍静态文件中间件之前,我们先介绍一下ContentRoot和WebRoot的概念。

ContentRoot:指web项目的文件夹,包括bin和webroot文件夹。

WebRoot:一般指ContentRoot路径下的wwwroot文件夹。

引入这两个概念是因为静态资源文件通常存储在WebRoot路径中,即wwwroot。下面是这两条路径的配置,如下所示:

公共静态void Main(字符串[]args){ var host=new WebHostBuilder()。UseKestrel()。UseStartupStartup()。UseContentRoot(目录。GetCurrentDirectory())。UseWebRoot(目录。GetCurrentDirectory()@ ' \ wwwroot \ ')。使用环境(EnvironmentName。发展)。build();主持人。run();}上面的代码配置了ContentRoot路径和WebRoot路径。事实上,只需要配置ContentRoot路径,WebRoot默认为ContentRoot路径下的wwwroot文件夹路径。

在了解静态文件中间件之前,我们还需要了解HTTP中静态文件缓存的机制。与静态文件相关的HTTP头主要有Etag和If-None-Match。

以下是访问静态文件服务器和客户端的过程:

1.客户端首先向客户端请求一个静态文件。

2.当服务器收到客户端访问静态文件的请求时,服务器会根据静态文件的上次修改时间和文件内容的长度生成一个Hash值,并将该值放入请求头ETag中。

3.当客户端第二次发起相同的请求时,因为文件之前被请求过,所以会有一个本地缓存。在请求中,If-辜莞允-Match被添加到请求头,它的值是服务器返回的ETag的值。

4.服务器端比较发送的如果不匹配值是否与本地ETag值相同。如果它们相同,则返回304状态代码,客户端继续使用本地缓存。如果它们不同,则返回状态代码200,客户端重新解析服务器返回的数据,而不使用本地缓存。

有关详细信息,请参见以下示例。

第二,使用简单

2.1最简单的用途

最简单的用法是在Configure中添加下面的句子,然后将静态文件放在webRoot的路径下。我没有修改webRoot指定的路径,所以它是wwwroot文件夹。

public void Configure(IApplicationBuilder应用程序,IHostingEnvironment env) { app。UseStaticFiles();app。UseMvc();}将名为1.txt的测试文本放在wwwroot文件夹下,然后通过地址访问。

这有一个缺点,显示此文件的路径在wwwroot下。

2.2指定请求地址

public void Configure(IApplicationBuilder应用程序,IHostingEnvironment env) { app。UseMvc();app。usestatifiles(new statifileoptions(){ file provider=new physicalfilepider(@ ' c : \ user \ Administrator \ Desktop '),request path=new path string('/Static ')});//app。使用静态文件('/Static ');}存储静态文件的路径是c: \用户\管理员\桌面。文件的真实路径是隐藏的,而不是使用默认的wwwroot路径,您需要在访问该地址之前向其添加静态路径。

当然,也可以只写请求路径,而不指定静态文件的路径,如上面代码中提到的例子。这样,静态文件必须存储在对应于WebRoot的目录中。如果WebRoot的目录对应wwwroot,静态文件将放在wwwroot文件夹中。

让我们通过一个例子来看看静态文件的缓存。如果你想做这个例子,别忘了先清空缓存。

(第一次请求)

(与第一次请求的文件相比,第二次请求的文件没有被修改)

(与第一个请求相比,第三个请求文件被修改)

三、源代码分析

源码在https://github.com/aspnet/StaticFiles,这个项目还包含有其他中间件。既然是中间件最重要的就是参数为上下文对象的引起方法了,因为每一个请求都要经过其处理,然后再交给下一个中间件处理。

下面为处理流程。

公共异步任务调用(HttpContext context){ var file context=new static file context(context,_options,_matchUrl,_logger,_fileProvider,_ contenttype provider);if(!文件上下文.ValidateMethod())//静态文件的请求方式只能是得到或者Head { _logger .LogRequestMethodNotSupported(上下文。请求。方法);} //判断请求的路径和配置的请求路径是否匹配。如请求路径为http://localhost :5000/static/1。txt//配置为RequestPath=新路径字符串('/静态')//则匹配,并将文件路径赋值给StaticFileContext中点的_subPath else if(!文件上下文.ValidatePath()) { _logger .日志路径不匹配(文件上下文。子路径);} //通过获取要访问文件的扩展名,获取此文件对应的哑剧类型, //如果找到文件对应的哑剧,返回没错,并将哑剧类型赋值给StaticFileContext中的_contextType //没有找到返回假的else if(!文件上下文.查找帐篷类型()){ _ logger .日志文件类型不受支持(文件上下文。子路径);} //判断访问的文件是否存在。 //如果存在返回没错,并根据文件的最后修改时间和文件的长度,生成混杂值,并将值赋值给_etag,也就是相应头中的艾塔格。//如果不存在返回假的,进入下一个中间件中处理else if(!文件上下文.LookupFileInfo()) { _logger .日志文件未找到(文件上下文。子路径);} else { fileContext .contractRequestHeaders();//根据StaticFileContext中的值,加上对应的相应头,并发送响应。具体调用方法在下面开关(文件上下文GetPreconditionState()){案例静态文件上下文.预条件状态。未指定:案例静态文件上下文。如果(文件上下文IsHeadMethod){等待文件上下文.发送状态同步(常量状态200正常);返回;}尝试{ if (fileContext .IsRangeRequest){等待文件上下文.sendRangeAsync();返回;}等待文件上下文发送异步();_记录器.日志文件服务(文件上下文。子路径,文件上下文. PhysicalPath);返回;} catch(FileNotFoundException){ context .响应。clear();} breakcase StaticFileContext .预处理状态NotModified: _logger .日志路径未修改(文件上下文。子路径);等待文件上下文。发送状态同步(常量。状态304未修改);返回;案例统计文件上下文.预处理状态。预处理失败: _记录器。日志预处理失败(文件上下文。子路径);等待文件上下文。发送状态同步(常量。状态412修复失败);返回;默认值: var异常=new notimplementdexception(文件上下文.GetPreconditionState().ToString());调试。失败(异常. ToString());引发异常;} } //进入下一个中间件中处理wait _next(上下文);}添加响应头的方法:

public void applyrresponseheaders(int statusCode){ _ response .status code=status code if(status code 400){ if(!字符串IsNullOrEmpty(_内容类型)){ _ response .内容类型=_内容类型}//设置响应头中最后修改时间、ETag和接受范围响应领导者.最后修改=_最后修改_响应领导者.ETag=_ etag_responseHeaders .标题[标题名称“AcceptRanges]=”字节;} if (statusCode==常量Status200Ok) { _response .ContentLength=_ length} _选项onpreparereresponse(new staticfilereresponsecontext(){ Context=_ Context,File=_fileInfo,});}校验文件是否修改的方法:

public bool LookupFileInfo(){ _ fileInfo=_文件提供程序.GetFileInfo(_subPath .价值);if (_fileInfo).存在){ _length=_fileInfo .长度;DateTimeOffset last=_fileInfo .LastModified_ last modified=新的日期时间偏移量(最后。去年。上个月。最后一天。最后一小时。最后一分钟。第二,最后。偏移量)。到世界时();//通过修改时间和文件长度,得到电子标签的值long etagHash=_lastModified .tofiletime()^ _长度;_etag=新的实体标签标题值(' \ '转换.ToString(etagHash,16)' \ ');} return _fileInfo .存在;}总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

版权声明:静态文件的详细说明 网络核心中间件是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。

相关文章推荐