面试常见-浏览器和网络(一)

131 阅读5分钟

前言

面试的时候经常会被问到网络相关的问题,我对网络相关的知识可以说是知之甚少,最近趁此机会学习和总结一下,希望在以后的面试当中不会再被难倒了。

URL组成

以下面这个url为例

www.example.com:80/path/to/myf…

  • protocol 协议:http、https、file等。通过location.protocol获取;
  • host域名:www.example.com就是url当中的域名。通过location.host获取;
  • prot端口:通常被忽略,http默认是80、https默认是443。通过location.port获取;
  • path路径:/path/to/myfile.html,网络资源在服务器中的路径。通过location.pathname获取;
  • query参数:?key1=value1&key2=value2,提供给网络服务器的额外参数。这些参数是用 符号分隔的键/值对列表;用location.search获取
  • hash锚点:#SomewhereInTheDocument,是资源本身的另一部分的锚点,值得注意的是,#后面的部分(也称为片段标识符)从来没有发送到请求的服务器。通过location.hash获取。

image.png

跨域

发起请求的资源所在域不同于该请求所指向资源所在的域的HTTP请求就叫做跨域HTTP请求

什么叫跨域?协议+域名+端口有一个不同就是跨域。比如http://www.example.com:80https://www.example.com:80发送请求。跨域的问题其实来自于浏览器的同源策略

同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。

其实跨域也就是说不同源,我们项目里经常需要跨域才能完成请求,怎么跨源网络访问呢?

document.domain

document.domain类似于location.href,调用获取域名,赋值修改域名。这个方法只适用于两个基础域名相同的子域名之间,比如aaa.example.com 和 bbb.example.com。在两个不同域名的页面下分别赋值document.domain='example.com',这样就实现跨域通信,不过这种方式已经不建议使用了。

image.png

postMessage

通过window.postMessage()方法向跨源页面发射一些信息,在接收的页面通过监听message事件来拿到发射的信息

image.png

image.png

image.png

需要注意的是这里的window必须是其他窗口的一个引用,比如 iframe 的 contentWindow 属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames

跨源资源共享(CORS)

跨源资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型 的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨源请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证 相关数据)。

简单请求

某些请求并不会触发cors预检请求,请求满足所有下述条件即可以视为简单请求

预检请求

预检请求必须首先使用options方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。比如下面就是一个需要执行"预检请求的http请求",因为请求头中加入了X-PINGOTHER

    const xhr = new XMLHttpRequest();
    xhr.open('POST', 'https://www.dotlog.kaochong.com/');
    xhr.setRequestHeader('X-PINGOTHER', 'pingpong');
    xhr.setRequestHeader('Content-Type', 'application/xml');
    xhr.onreadystatechange = function (res) {
      console.log(res);
    };
    xhr.send('<person><name>Arun</name></person>');

image.png 这里可以看到这里多了一个preflight类型options请求,告诉他我要发送一个post请求,如果有凭证信息,这里也会校验凭证信息。

HTTP 响应首部字段

这里主要涉及到前端和后端的交互了,即xmlhttprequest请求,通常的做法是在http请求头和响应头上分别加上规范定义的首部字段。

  • Access-Control-Allow-Origin 参数指定了允许访问资源的外域,也可以用*允许所有域的请求。比如这里指定了只有从kaochong.com发起的请求不会出现跨域

image.png

  • Access-Control-Allow-Methods 首部字段用于预检请求的响应。其指明了实际请求中允许携带的首部字段。比如这里如果用put请求就是不允许的

image.png

  • Access-Control-Allow-Headers 首部字段用于预检请求的响应。其指明了实际请求中允许携带的首部字段

image.png

  • Access-Control-Allow-Credentials 指定了当浏览器的 credentials 设置为 true 时是否允许浏览器读取 response 的内容。比如我们向后端发起请求的时候需要携带cookie,但是响应头里没有设置true,即使请求头中写携带了cookie,浏览器也不会把得到的响应内容返回给请求者。

image.png

HTTP 请求首部字段

  • Origin 表明预检请求或实际请求的源站。 image.png

结语

这里只总结了一小部分,之后会总结其他的部分。写的不好,各位大佬多多指教,感恩家人🙏