使用 fetch() API 返回部分视图

Posted

技术标签:

【中文标题】使用 fetch() API 返回部分视图【英文标题】:Returning partial views with the fetch() API 【发布时间】:2018-02-14 05:43:28 【问题描述】:

fetch API 是旧 XMLHttpRequest API 的现代替代品。

jQuery、MooTools、Prototype 和 Zepto 等许多 javascript 库添加了非标准的 X-Requested-With 请求标头,该标头已成为事实上的标准,并且许多 JavaScript 库以及 Web 应用程序框架都支持,例如 Ruby on Rails、Laravel、Sinatra、Spring、Symfony、ASP.NET MVC 等。

随着 JavaScript 对 jQuery 的现代化改造,jQuery 已经失去了重要地​​位,AngularJS 曾经发送 XMLHttpRequest 标头,但现在不再这样做了。 ASP.NET Core MVC 不再包含 IsAjaxRequest 扩展方法。

许多 Web 应用程序框架都有“部分视图”的概念,因此它可以返回没有页眉和页脚的视图。

如何响应fetch() 请求返回部分视图?

我可以将 X-Requested-With 标头添加到 fetch 请求中,但似乎有 some people 反对声称这是一个非标准标头并且它破坏了某些 Web 代理中的缓存,它可能导致额外的飞行前 OPTIONS 请求等。

这些人说应该改用Accept 标头。但我该怎么做呢?我想为这两种类型的请求返回 html 内容,只是 fetch() 请求应该获取页面的子集(内容但没有页眉和页脚)。

Accept 标头的值是多少?

if page_is_requested_by_fetch_api:
    return content
else:
    return header + content + footer

在我看来,Accept 标头似乎无法使用。我不明白它可以如何使用。正常请求页面和请求部分视图时,我需要 HTML 内容,即text/html

我是否应该使用 Accept 标头并发明自己的非标准 MIME 类型,例如 text/partial+html ? 我是否应该将X-Requested-With 添加到我的 fetch() 请求的标头中? 我是否应该附加一个查询字符串,例如/page?type=partialview? 我应该有不同的 HTTP 端点,例如 /Account/Login/Account/LoginPartial 吗? 我是否应该获取整个页面、解析 DOM 并提取 <main> 元素的内容?

【问题讨论】:

至于问题“我应该获取整个页面,解析 DOM 并提取
元素的内容吗?”
,我不是确定其他人可以说那是你绝对应该做的——但至少这会总是有效,对吧?我的意思是它始终可以正常工作,而您无需在发送请求的服务器端进行任何更改。
就问题中的其他项目符号而言,其余的取决于您将请求发送到的服务器上运行的后端是什么,对吧?如果该服务器后端内置了一些特殊的支持来发送部分视图,那么您可以使用服务器公开的任何 API 或网络协议来让您获得部分视图。或者你是在问你应该在这样的服务器后端实现什么机制来提供部分视图?我的意思是,如果现有的服务器后端还没有为此公开一些东西,应该实现什么机制? @sideshowbarker 我正在编写前端和后端代码。所以我想知道使用 fetch API 处理部分视图的正确方法是什么。我控制客户端和服务器的实现。 好吧,我想这相当于,Fetch API 本身并没有为此内置任何特殊功能。基本上,它在功能上与 XHR 相同。 Fetch API 确实让您可以直接控制 XHR 不允许您控制的请求的某些方面——但仅限于较低级别的方面。它归结为:Fetch API 是一个相对低级的 API,它只是对底层浏览器引擎的低级内部获取行为提供了一个相对薄的抽象。如果你想要更多,你需要使用一些提供更高级别抽象的 JavaScript Ajax 库 【参考方案1】:

您的问题:如何返回部分视图以响应 fetch() 请求?

我自己将它与 Razor Pages 一起使用。这是javascript代码

fetch(url)
        .then((response) =>  return response.text(); )
        .then((result) => 
                $('#container').html(result);
        );

这是 cshtml.cs 文件中的代码。我想 MVC 中的控制器也是一样的:

public async Task<PartialViewResult> OnGetSomeObjectList()

    return new PartialViewResult()
    
        ViewName = "NAME_OF_PARTIAL_VIEW",
        ViewData = new ViewDataDictionary<IEnumerable<object>>(ViewData, new List<object>()
        
            new object(),
            new object()
        )
    ;

【讨论】:

但是您的 Web 应用程序仅适用于部分视图,如果您要通过打开新选项卡导航到该端点,或者想要为其添加书签或共享链接,那么它将呈现部分视图查看而不是整页。

以上是关于使用 fetch() API 返回部分视图的主要内容,如果未能解决你的问题,请参考以下文章

React Native Fetch API json返回旧数据

Wordpress 在使用 fetch API 的 ajax 调用上返回 400 Bad Request

在反应中使用fetch时的null [FormBody]字符串值

Mailchimp API 在使用 node-fetch 而不是 json 时返回一个大的 gzip 对象

FETCH API 返回 [object Object]

将 fetch 与 async/await 一起使用会返回 [object Object]