jjzjj

javascript - Angular:Http 与 fetch api

coder 2024-07-18 原文

虽然我了解 Angular 发出 HTTP 请求的方式,但我更喜欢使用内置的 Fetch API,因为我不必为了发出 1 个简单的请求而订阅和取消订阅。我尝试在我的 angular 应用程序中使用它,但没有抛出任何错误,页面没有重新加载(仍然是 SPA),一切正常。我想一切都有时间和地点。

这个:

fetch('/api/get_post_by_id/1').then(r => r.json()).then(j => { console.log(j); });

比这更简单:
const obs = this.http.get('/api');
obs.subscribe(() => { ... });
obs.unsubscribe();

基本上我的问题是,在开发 Angular 应用程序时使用 Fetch API 是错误的吗?

最佳答案

就像您在开发过程中遇到的任何工具一样,每个工具都有优点和缺点,最好考虑一下为什么要使用工具。
当我们看看HttpClient它最初简化了 XMLHttpRequest 的困惑局面.同理$.ajax原来是这样做的,HttpClient是“Angular 解决方案”。它遵循一切都是可观察的意识形态,它具有优点(您可以将它与其他可观察对象混合和匹配)和缺点(它会增加很多膨胀)。HttpClient的优势

  • 它允许轻松混合和匹配两个 observable(例如,假设您有一个返回多次的 observable 和一个返回一次的 API 请求,并且您想将两者压缩在一起,这很容易做到)。当然,将promise 变成observable 只需要导入from来自 rxjs
  • 如果您忘记添加抽象 - 让所有请求都通过 apiService layer - 你仍然可以使用拦截器神奇地实现类似的结果。
  • 它将增加新 Angular 开发人员的学习曲线,从而使您的工作更加特别。
  • HttpClient为您做一些神奇的事情,例如自动重试请求。
  • 它已经包含在 Angular 中,所以如果你需要支持像 IE11 这样的 7 岁浏览器,你不需要像 fetch 那样加载 polyfill。 .
  • fetch的优势
    重要 :所有与 fetch 相关的代码都假设您确实创建了一个非常简单的抽象(例如这些示例中的 apiService)。这和在HttpClient中设置拦截器是一样的-土地。
  • 这是新的行业标准。一旦你知道它,它就可以在任何地方使用(很可能一旦 Angular 和 React 死了 - 在某些时候它们会 - fetch 很可能仍然存在)。
  • 它简化了与服务 worker 的合作,如 RequestResponse对象与您在普通代码中使用的相同。
  • HTTP 请求通常只会返回一次(当然,您可能正在逐块加载文件,但这是规则的一个非常罕见的异常(exception))。 fetch围绕规范(单个返回值)而不是异常(多个返回值)构建,因此返回 Promise而不是类似流的类型。这样做的好处是它可以很好地与任何和所有相关的新语言功能一起使用,例如 asyncawait .相比:
     try {
         const posts = await this.apiService.get('/posts');
         // work with posts
     } catch (error) {
         // handle error
     }
     console.log('this happens **after** the request completes');
    
     this.http.get('/posts')
         .subscribe(posts => {
             // work with posts
         })
         .catch(error => {
             // work with error
         });
     console.log('this happens **before** the request completes');
    
    (当然你也可以 toPromise 每个将完成的 Observable (或添加 .pipe(take(1)) ,但坦率地说,这是一堆多余的代码(我仍然经常使用))
  • 它简化了新人的入职。当您看到诸如
     this.apiService.get('/posts');
    
    来自任何框架的开发人员都可以右键单击 .get并查看函数定义,其中将明确定义域和身份验证 header 等内容。
    另一方面,当开发人员看到
     this.http.get('/posts')
    
    除非他们知道 Angular 特定的魔法,否则他们无法轻松发现请求是否以及在何处可能被更改。这是 Angular 被认为具有陡峭学习曲线的原因之一。
  • 不存在您不知道的魔法风险,例如自动重试请求可能会在同一请求中触发 4 次在服务器上,而您不知道这是怎么可能的。
  • 它已经包含在浏览器中——前提是你不需要支持 7 岁的浏览器——所以它可以导致包的大小略小。

  • 完整的领带
  • 我真的不明白类型有什么不同,因为可以从任何方法输入返回值。 <Model>this.apiService.get('/posts')工作得很好。

  • 结论
    就个人而言,我强烈建议任何人使用 fetch带有抽象层。它使代码更易于阅读(即使是从未见过 asyncawait 的大三学生也能阅读它),即使您遇到了 apiService 的罕见情况。必须多次返回,您仍然可以完全自由地这样做,因为您完全可以控制。一般而言,如果替代方案具有显着优势,则不应使用标准 ( fetch )。即使它在优点和缺点方面完美结合,也可能不值得采用“特定于框架”的解决方案。HttpClient除了在初始项目设置期间节省几分钟的时间之外,您无需为 API 请求设置抽象层,似乎并没有提供任何切实的优势。

    关于javascript - Angular:Http 与 fetch api,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53660262/

    有关javascript - Angular:Http 与 fetch api的更多相关文章

    1. ruby - 如何模拟 Net::HTTP::Post? - 2

      是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

    2. ruby - Net::HTTP 获取源代码和状态 - 2

      我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

    3. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

      1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

    4. ruby-on-rails - Rails - 从命名路由中提取 HTTP 动词 - 2

      Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba

    5. ruby-on-rails - Heroku 吃掉了我的自定义 HTTP header - 2

      我正在使用Heroku(heroku.com)来部署我的Rails应用程序,并且正在构建一个iPhone客户端来与之交互。我的目的是将手机的唯一设备标识符作为HTTPheader传递给应用程序以进行身份​​验证。当我在本地测试时,我的header通过得很好,但在Heroku上它似乎去掉了我的自定义header。我用ruby​​脚本验证:url=URI.parse('http://#{myapp}.heroku.com/')#url=URI.parse('http://localhost:3000/')req=Net::HTTP::Post.new(url.path)#boguspara

    6. ruby-on-rails - 使用 HTTP.get_response 检索 Facebook 访问 token 时出现 Rails EOF 错误 - 2

      我试图在我的网站上实现使用Facebook登录功能,但在尝试从Facebook取回访问token时遇到障碍。这是我的代码:ifparams[:error_reason]=="user_denied"thenflash[:error]="TologinwithFacebook,youmustclick'Allow'toletthesiteaccessyourinformation"redirect_to:loginelsifparams[:code]thentoken_uri=URI.parse("https://graph.facebook.com/oauth/access_token

    7. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

      我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

    8. ruby - HTTP 请求中的用户代理,Ruby - 2

      我是Ruby的新手。我试过查看在线文档,但没有找到任何有效的方法。我想在以下HTTP请求botget_response()和get()中包含一个用户代理。有人可以指出我正确的方向吗?#PreliminarycheckthatProggitisupcheck=Net::HTTP.get_response(URI.parse(proggit_url))ifcheck.code!="200"puts"ErrorcontactingProggit"returnend#Attempttogetthejsonresponse=Net::HTTP.get(URI.parse(proggit_url)

    9. ruby - 如何使用 Ruby HTTP::Net 处理 404 错误? - 2

      我正在尝试解析网页,但有时会收到404错误。这是我用来获取网页的代码:result=Net::HTTP::getURI.parse(URI.escape(url))如何测试result是否为404错误代码? 最佳答案 像这样重写你的代码:uri=URI.parse(url)result=Net::HTTP.start(uri.host,uri.port){|http|http.get(uri.path)}putsresult.codeputsresult.body这将打印状态码和正文。

    10. ruby - 让 bundler 使用 http : instead of git:? - 2

      我正在安装gitlabhq,并且在Gemfile中有对某些资源的“git://...”的引用。但是,我在公司防火墙后面,所以我必须使用http://。我可以手动编辑Gemfile,但我想知道是否有另一种方法告诉bundler使用http://作为git存储库? 最佳答案 您可以通过运行gitconfig--globalurl."https://".insteadOfgit://或通过将以下内容添加到~/.gitconfig:[url"https://"]insteadOf=git://

    随机推荐