前端面试题总结

本文详细探讨了前端面试中常见的问题,涵盖了GET和POST请求的区别,包括它们在浏览器使用和接口调用中的应用场景,安全性考量,以及HTTP请求的结构。此外,还涉及HTML的position属性、URL长度限制、CSS3新特性、JavaScript事件处理、SVG与canvas的对比、深拷贝、HTTP与HTTPS的区别、跨域问题、变量提升和暂时性死区的概念,以及数组和对象的处理。文章深入浅出,是准备前端面试的宝贵参考资料。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.GET 和 POST 到底有什么区别? - 大宽宽的回答 - 知乎

提交数据的形式:

  • GET:附在URL后,展现在地址栏中
  • POST:数据放在请求字段中

提交数据的大小:

  • GET:影响了URL的长度,限制URL长度的是客户端和服务器的支持的不同
  • POST:起限制作用的是服务器处理程序的处理能力

安全性:

  • GET:明文出现在URL上,比POST弱
    • (1)登录页面有可能被浏览器缓存
    • (2)其他人查看浏览器的历史纪录,那么别人就可 以拿到你的账号和密码了
    • (3)当遇上跨站的攻击时,安全性的表现更差了

 

1.1 场景一:浏览器使用的GET/POST

浏览器中非AJAX的HTTP请求,HTTP协议中的GET/POST

浏览器用GET请求来获取一个html页面/图片/css/js等资源;用POST来提交一个<form>表单,并得到一个结果的网页

1.1.1 GET

“读取“一个资源,反复读取不应该对访问的数据有副作用 [没有副作用被称为“幂等“(Idempotent)]

可以对GET请求的数据做缓存:

  • 缓存可以做到浏览器本身上(彻底避免浏览器发请求)
  • 也可以做到代理上(如nginx)
  • 或者做到server端(用Etag,至少可以减少带宽消耗)

1.1.2 POST

<form> 标签定义一个表单,点击其中的submit元素发出一个POST请求让服务器做一件事。

  • 有副作用的
  • 不幂等的——不能随意多次执行——不能缓存——不能把POST请求保存为书签——尝试重新执行POST请求,浏览器也会弹一个框提示下这个刷新可能会有副作用,询问要不要继续

泛泛的说“GET请求没有body,只有url,请求数据放在url的querystring中;POST请求的数据在body中“。但这种情况仅限于浏览器发请求的场景

 1.2 场景二:接口中的GET和POST

指通过浏览器的Ajax api,或者iOS/Android的App的http client,java的commons-httpclient/okhttp或者是curl,postman之类的工具发出来的GET和POST请求。此时GET/POST不光能用在前端和后端的交互中,还能用在后端各个子服务的调用中(即当一种RPC协议使用)。

为什么使用这个:http本身已经有大量的现成的支持工具可以使用,并且对人类很友好,容易debug。HTTP协议在微服务中的使用是相当普遍的。

HTTP请求的格式:

<METHOD> <URL> HTTP/1.1\r\n
<Header1>: <HeaderValue1>\r\n
<Header2>: <HeaderValue2>\r\n
...
<HeaderN>: <HeaderValueN>\r\n
\r\n
<Body Data....>

“<METHOD>"可以是GET也可以是POST,或者其他的HTTP Method,如PUT、DELETE、OPTION等

参数可以放在url的path里,querystring里,body里,header里

因此,制定接口规范/风格,如REST:

REST充分运用GET、POST、PUT和DELETE,约定了这4个接口分别获取、创建、替换和删除“资源”,REST最佳实践还推荐在请求体使用json格式。这样仅仅通过看HTTP的method就可以明白接口是什么意思,并且解析格式也得到了统一。

REST中GET和POST不是随便用的。

在REST中, 【GET】 + 【资源定位符】被专用于获取资源或者资源列表。与浏览器的场景类似,REST GET也不应该有副作用,于是可以被反复无脑调用。浏览器(包括浏览器的Ajax请求)对于这种GET也可以实现缓存。

REST 【POST】+ 【资源定位符】则用于“创建一个资源”——浏览器中用来实现表单提交的POST,和REST里实现创建资源的POST语义上的不同。

POST http://foo.com/books
{
  "title": "大宽宽的碎碎念",
  "author": "大宽宽",
  ...
}

REST POST和REST PUT的区别(有些api是使用PUT作为创建资源的Method)

PUT与POST的区别在于,PUT的实际语义是“replace”replace。REST规范里提到PUT的请求体应该是完整的资源,包括id在内。服务器应该先根据请求提供的id进行查找,如果存在一个对应id的元素,就用请求中的数据整体替换已经存在的资源;如果没有,就用“把这个id对应的资源从【空】替换为【请求数据】“。直观看起来就是“创建”了。

与PUT相比,POST更像是一个“factory”,通过一组必要的数据创建出完整的资源。

1.3 安全性

无论是GET还是POST都不够安全,因为HTTP本身是明文协议每个HTTP请求和返回的每个byte都会在网络上明文传播,不管是url,header还是body

为了避免传输中数据被窃取,必须做从客户端到服务器的端端加密。业界的通行做法就是https——即用SSL协议协商出的密钥加密明文的http数据。这个加密的协议和HTTP协议本身相互独立。如果是利用HTTP开发公网的站点/App,要保证安全,https是最最基本的要求。

//端端加密并不一定非得用https。比如国内金融领域都会用私有网络,也有GB的加密协议SM系列。

GET请求的参数更倾向于放在url上,因此有更多机会被泄漏。

从客户端到服务器端,有大量的中间节点,包括网关,代理等。他们的access log通常会输出完整的url,比如nginx的默认access log就是如此。如果url上携带敏感数据,就会被记录下来。但请注意,就算私密数据在body里,也是可以被记录下来的,因此如果请求要经过不信任的公网,避免泄密的唯一手段就是https。这里说的“避免access log泄漏“仅仅是指避免可信区域中的http代理的默认行为带来的安全隐患。

一般情况下,私密数据传输用POST + body就好。

1.4 HTTP请求

“请求头”:所有的“控制类”信息应该放在请求头中

“请求体”:具体的数据放在请求体里

服务器端在解析时,总是会先完全解析全部的请求头部。这样,服务器端总是希望能够了解请求的控制信息后,就能决定这个请求怎么进一步处理,是拒绝,还是根据content-type去调用相应的解析器处理数据,或者直接用zero copy转发。

为了进一步优化,客户端可以利用HTTP的Continued协议来这样做:客户端总是先发送所有请求头给服务器,让服务器校验。如果通过了,服务器回复“100 - Continue”,客户端再把剩下的数据发给服务器。如果请求被拒了,服务器就回复个400之类的错误,这个交互就终止了。这样,就可以避免浪费带宽传请求体。但是代价就是会多一次Round Trip。如果刚好请求体的数据也不多,那么一次性全部发给服务器可能反而更好。

基于此,客户端就能做一些优化,比如内部设定一次POST的数据超过1KB就先只发“请求头”,否则就一次性全发。客户端甚至还可以做一些Adaptive的策略,统计发送成功率,如果成功率很高,就总是全部发等等。不同浏览器,不同的客户端(curl,postman)可以有各自的不同的方案。不管怎样做,优化目的总是在提高数据吞吐降低带宽浪费上做一个折衷。

从HTTP协议的角度,“请求头”就是Method + URL(含querystring)+ Headers;再后边的都是请求体。

从业务角度,如果你把一次请求立即为一个调用的话。这一行函数名和两个参数都可以看作是一个请求,不区分头和体

对于HTTP,需要区分【头】和【体】,Http Request和Http Response都这么区分。Http这么干主要用作

  • 对于HTTP代理
    • 支持转发规则,比如nginx先要解析请求头,拿到URL和Header才能决定怎么做(转发proxy_pass,重定向redirect,rewrite后重新判断……)
    • 需要用请求头的信息记录log。尽管请求体里的数据也可以记录,但一般只记录请求头的部分数据。
    • 如果代理规则不涉及到请求体,那么请求体就可以不用从内核态的page cache复制一份到用户态了,可以直接zero copy转发。这对于上传文件的场景极为有效。
    • ……
  • 对于HTTP服务器
    • 可以通过请求头进行ACL控制,比如看看Athorization头里的数据是否能让认证通过
    • 可以做一些拦截,比如看到Content-Length里的数太大,或者Content-Type自己不支持,或者Accept要求的格式自己无法处理,就直接返回失败了。
    • 如果body的数据很大,利用Stream API,可以方便支持一块一块的处理数据,而不是一次性全部读取出来再操作,以至于占用大量内存。
    • ……

1.4.1 http请求报文结构

一个HTTP请求报文由四个部分组成:请求行、请求头部、空行、请求数据

  • 请求行:由请求方法字段、URL字段和HTTP协议版本字段3个字段组成,它们用空格分隔。
    • 方法字段就是HTTP使用的请求方法,比如常见的GET/POST、PUT、DELETE、OPTION
    • HTTP协议版本有两种:HTTP1.0/HTTP1.1
      • HTTP1.0对于每个连接都只能传送一个请求和响应,请求就会关闭,HTTP1.0没有Host字段;
      • 而HTTP1.1在同一个连接中可以传送多个请求和响应,多个请求可以重叠和同时进行,HTTP1.1必须有Host字段。
  • 请求头部:大多数请求头并不是必需的,但Content-Length除外。对于POST请求来说 Content-Length必须出现。
    • 常见的请求头字段:Accept、Accept-Charset、Accept-Encoding、Accept-Language、Content-Length、Cookie等
  • 空行:告诉服务器请求头部到此为止
  • 请求数据:
    • 若方法字段是GET,则此项为空,没有数据

    • 若方法字段是POST,则通常来说此处放置的就是要提交的数据

1.4.2 HTTP响应报文

HTTP响应报文也由三部分组成:响应行、响应头、响应体

  • 响应行:一般由协议版本、状态码及其描述组成
    • 协议版本HTTP/1.1或者HTTP/1.0
    • 状态码:
      • 200:这个是最常见的http状态码,表示服务器已经成功接受请求,并将返回客户端所请求的最终结果
      • 301:永久重定向
      • 302:临时重定向
      • 404:资源未找到
      • 403:服务器拒绝访问
      • 500:服务器遇到未知的错误
      • 503:服务器由于临时的服务器过载或者是维护,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值