目录
题目
单选题1
题解
关于浏览器缓存
Last-Modified/If-Modified-Since
ETag/If-None-Match
关于浏览器删除缓存数据
单选题2
题解
跨域问题
用document.domain解决的问题
题目
单选题1
1.关于浏览器缓存,以下哪个选项是不正确的()
A. 浏览器缓存可以帮助减少服务器的负载,提高网页加载速度。
B. 浏览器缓存包括强缓存和协商缓存两种。
C. Http头信息中的"Cache-Control"和"Etag"分别是强缓存和协商缓存的关键字段。
D. 当浏览器缓存过期,浏览器会直接删除缓存数据,不会向服务器发送请求。
题解
关于浏览器缓存
浏览器缓存是一种重要的网络技术,缓存是为了减少网页加载时间和减轻服务器负载,通过存储已下载的资源,比如HTML页面、图片,JavaScript文件,CSS样式表,这会提高网页加载速度。同时,浏览器缓存主要有两种类型,即强缓存和协商缓存。
强缓存是根据http头信息中的'Cache-Control',或者'Expires'字段来判断资源是否过期的,比如说Expires就会提供一个特定的日期或者时间,指明资源会何时过期。
协商缓存的工作原理是:当强缓存过期后,浏览器会向服务器发送请求,询问缓存内容是否仍然有效。这种方式靠关键HTTP头字段,来判断是否要对资源进行缓存。有两种:第一种是Last-Modified和If-Modified-Since,第二种是ETag和If-None-Match,比如说下面的代码。
Last-Modified/If-Modified-Since
服务器响应如下图,当浏览器首次请求一个资源时,服务器在响应头中加入Last-Modified字段,这个字段表示了资源最后一次被修改的时间。接着,浏览器会发出这样的请求,它会在请求头中包含一个If-Modified-Since字段,其值即为之前服务器发送的Last-Modified。
HTTP/1.1 200 OK
Date: Sat, 28 Jan 2024 12:00:00 GMT
Last-Modified: Wed, 25 Jan 2024 08:00:00 GMT
Content-Type: image/jpeg
Content-Length: 1024
GET /image.jpg HTTP/1.1
Host: www.example.com
If-Modified-Since: Wed, 25 Jan 2024 08:00:00 GMT
ETag/If-None-Match
这种方式就是字段的内容不一样,功效都是浏览器向服务器询问缓存内容是否有效。服务器会提供一个ETag字段。当浏览器再次请求该资源时,发送的信息就会包含If-None-Match字段。
HTTP/1.1 200 OK
Date: Sat, 28 Jan 2024 12:00:00 GMT
ETag: "9e107d9d372bb6826bd81d3542a419d6"
Content-Type: image/jpeg
Content-Length: 1024
GET /image.jpg HTTP/1.1
Host: www.example.com
If-None-Match: "9e107d9d372bb6826bd81d3542a419d6"
关于浏览器删除缓存数据
首先说一下,D选项明显错误,浏览器删除缓存数据,是有很多种情况的。仅就删除缓存数据而言,有用户端手动删除缓存数据和强缓存转向协商缓存,两种情况。对于用户手动删除缓存数据,我们不管浏览器缓存是否会过期,而是根据用户自己的选择,比如本地空间有限,我们就不会考虑缓存数据过期的问题,直接就删除了。
而对于第二种情况,强缓存转向协商缓存,这种情况是,当资源的强缓存过期时,浏览器不会立即删除缓存数据,这时候浏览器会进入协商缓存阶段,向服务器发送请求来验证缓存的内容是否仍然有效。
综上所述,答案选择D。
单选题2
2.关于浏览器的同源策略和跨域,以下哪个选项是不正确的()
A. 同源策略是浏览器的一种安全策略,不同源的客户端脚本在没有明确授权的情况下,不能读/写对方的资源。
B. 如果协议、域名或端口任何一个不同,就能造成跨域。
C. 通过设置document.domain可以解决所有跨域问题。
D. JSONP和CORS是常见的跨域解决方案。
题解
跨域问题
跨域,完整的说法是,跨域资源共享,Cross-Origin Resource Sharing,是用于让网页的受限资源能够被其他域名的页面访问的一种机制,我们可以从一个网址,用AJAX来访问另一个网址的资源。协议,域名或者端口,有任何一个不同,都会造成跨域,比如http://example.com和https://example.com就是跨域,因为协议不同。
跨域的解决方案有多种。不同的方法,有不同的使用场景,各有优劣。
跨域解决方法 | 原理 | 注意点 |
---|---|---|
JSONP(JSON with Padding) | 通过动态创建<script>元素,请求一个带有回调函数的URL | 仅支持GET请求 |
CORS(Cross-Origin Resource Sharing) | CORS是一个W3C标准,允许服务器通过设置特殊的HTTP头部,来指示浏览器允许本次跨域请求 | 服务器设置如Access-Control-Allow-Origin的HTTP响应头部 |
使用代理服务器 | 在服务器端设置一个代理,接收前端发出的跨域请求,然后把这个请求转发给目标服务器,最后把结果返回给前端 | 可以绕过浏览器的同源策略限制 |
这里提到的同源策略,刚好就是A选项说的内容,同源策略是浏览器的一种安全策略,主要用于防止来自不同源的脚本对当前源的文档或者窗口进行读写操作,这样做,就是为了在不同源的客户端脚本在没有明确授权的情况下,不能读或写对方的资源。
用document.domain解决的问题
首先看看这种方法能解决什么问题。来一个具体的例子,www.google.com,这是一个完整的URL,主域即google.com,子域则为www,当然,www是最常见的子域,还有比如aws这样子域。请记住,document.domain只能解决同主域下的不同子域之间的跨域问题。
来看看代码吧,现在假设一个场景,我们想要从a.example.com页面访问b.example.com页面中的一个iframe,但由于同源策略,不同的子域在没有适当设置的情况下,不能直接通信。首先,在一个html文件中,我们写下这样的内容。我们尝试访问iframe中的内容,然后在另一个html文件中,使用document.domain,设置为主域的地址,即可完成目标。所以,document,domain只能解决这种情况,不能解决所有的跨域问题。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>a.example.com</title><script>function accessIframe() {let iframe = document.getElementById('myIframe');let iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
// 尝试访问iframe中的内容let content = iframeDocument.getElementById('content').innerText;alert("内容从b.example.com iframe获取: " + content);}</script>
</head>
<body><h1>欢迎来到 a.example.com</h1><iframe id="myIframe" src="http://b.example.com/iframe.html" onload="accessIframe()" width="300" height="200"></iframe>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>b.example.com</title>
</head>
<body><div id="content">这是来自 b.example.com 的内容!</div><script>// 设置document.domain为共同的主域document.domain = 'example.com';</script></body>
</html>