跨域问题备忘录

141 阅读3分钟

1. 除了请求,还有什么内容会跨域呢

Same-origin-policy提到的典型跨域案卷中发现了这个:

image.png

大体意思是,img,video等虽然在通常情况下可以被跨域嵌入(例如img,video标签嵌入图片,视频等),但是跨院域取是被禁止的。

有哪些跨域读取呢,尝试了一些案例:(8095端口为同源)

canvas跨域getImageData读取

// html
<img src="http://127.0.0.1:8092/images/arrow.png" alt="" id="crossoriginImage" onload="getPic('crossoriginImage')">
<img src="http://127.0.0.1:8095/images/arrow.png" alt="" id="sameoriginImage" onload="getPic('sameoriginImage')">
// js
function getPic (imageId) {
    const arrowImage = document.getElementById(imageId);
    const canvasDom = document.createElement("canvas")
    const ctx = canvasDom.getContext("2d");
    ctx.drawImage(arrowImage, 0, 0, 100, 100)
    const result = ctx.getImageData(0, 0, 100, 100)
    console.log(imageId, result)
}

可以看到,同源图片数据(sameoriginImage)能正常读取, 跨域图片数据读取报错

image.png

shape-outside功能

css的shape-outside功能,可以让字体贴着图片形状摆放。也是禁止使用跨域资源的

// html
<div class="box">
    <img src="http://127.0.0.1:8092/images/road.png" alt="star">
    <p>One November night in the year 1782, so the story runs, two brothers sat over their winter fire in the little French town of Annonay, watching the grey smoke-wreaths from the hearth curl up the wide chimney. Their names were Stephen and Joseph Montgolfier, they were papermakers by trade, and were noted as possessing thoughtful minds and a deep interest in all scientific knowledge and new discovery. Before that night—a memorable night, as it was to prove—hundreds of millions of people had watched the rising smoke-wreaths of their fires without drawing any special inspiration from the fact.</p>
</div>
<div class="samesite-box">
    <img src="http://127.0.0.1:8095/images/road.png" alt="star">
    <p>One November night in the year 1782, so the story runs, two brothers sat over their winter fire in the little French town of Annonay, watching the grey smoke-wreaths from the hearth curl up the wide chimney. Their names were Stephen and Joseph Montgolfier, they were papermakers by trade, and were noted as possessing thoughtful minds and a deep interest in all scientific knowledge and new discovery. Before that night—a memorable night, as it was to prove—hundreds of millions of people had watched the rising smoke-wreaths of their fires without drawing any special inspiration from the fact.</p>
</div>

// css
.box img {
    float: left;
    shape-outside: url('http://127.0.0.1:8092/images/road.png');
}
.samesite-box img {
    float: left;
    shape-outside: url('http://127.0.0.1:8095/images/road.png');
}

结果如下:

image.png

可以看到,使用同源图片的话,是有贴边功能的。而跨域图片的贴边功能是无效的。

image.png 同时,在控制台可以看到有图片跨域。

chrome中的font-face

在chrome中,使用font-face也会导致跨域

@font-face {
  font-family: "test";
  src: url("http://127.0.0.1:8092/font/iconfont.ttf") format("TrueType")
}

image.png

2. 关于简单请求的定义

在跨域请求的流程中,简单请求是不会发送预请求(option)的,但是目前对MDN中关于简单请求的描述存疑。

MDN中的描述

若请求满足所有下述条件,则该请求可视为简单请求

备注:  Firefox 还没有将 Range 实现为安全的请求标头。参见 bug 1733981

  • Content-Type 标头所指定的媒体类型的值仅限于下列三者之一:

    • text/plain
    • multipart/form-data
    • application/x-www-form-urlencoded
  • 如果请求是使用 XMLHttpRequest 对象发出的,在返回的 XMLHttpRequest.upload 对象属性上没有注册任何事件监听器;也就是说,给定一个 XMLHttpRequest 实例 xhr,没有调用 xhr.upload.addEventListener(),以监听该上传请求。

  • 请求中没有使用 ReadableStream 对象。

同时满足5种,4,5两点我看不太明白,但是第3点也有问题呀,我在nginx增加了跨域配置,允许图片跨域,可以看到:

image.png 图片也是一个简单请求,并且content-type也并非MDN中描述的三种。

处理方案

这里找到一个可以判断请求是否需要发送CORS预请求的地址httptoolkit.com/will-it-cor…

以后就不管啥是否是简单请求了,用这个测试就完事了。