古城皓月 發表於 2020-8-10 11:02:00

CORS 如果需要指定多个域名怎么办

<p><code>CORS</code>&nbsp;通过控制&nbsp;<code>Access-Control-Allow-Origin</code>&nbsp;控制哪些域名可以共享资源,取值如下</p>
<div class="cnblogs_code">
<pre>Access-Control-Allow-Origin: &lt;origin&gt; | *</pre>
</div>
<div>
<div>
<p>其中 <code>*</code> 代表所有域名,<code>origin</code> 代表指定特定域名,那如何设置多个域名了?</p>
<p>此时需要通过代码实现,<strong>根据请求头中的 <code>Origin</code> 来设置响应头 <code>Access-Control-Allow-Origin</code></strong>,那 Origin 又是什么东西?</p>
<h3 class="heading" data-id="heading-12">请求头: Origin</h3>
</div>
<div>
<p>并不是所有请求都会自动带上 <code>Origin</code>,在浏览器中带 <code>Origin</code> 的逻辑如下</p>
<ol>
<li>如果存在跨域,则带上 <code>Origin</code>,值为当前域名</li>
<li>如果不存在跨域,则不带 <code>Origin</code></li>
</ol>
<p>逻辑理清楚后,关于服务器中对于 <code>Access-Control-Allow-Origin</code> 设置多域名的逻辑也很清晰了</p>
<ol>
<li>如果请求头不带有 <code>Origin</code>,证明未跨域,则不作任何处理</li>
<li>如果请求头带有 <code>Origin</code>,证明跨域,根据 <code>Origin</code> 设置相应的 <code>Access-Control-Allow-Origin: &lt;Origin&gt;</code></li>
</ol>
<p>使用伪代码实现如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获取 Origin 请求头</span>
const requestOrigin = ctx.get('Origin'<span style="color: rgba(0, 0, 0, 1)">);

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 如果没有,则跳过</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">requestOrigin) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> await next();
}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 设置响应头</span>
ctx.set('Access-Control-Allow-Origin', requestOrigin)</pre>
</div>
<div>
<div>
<h3 class="heading" data-id="heading-13">Vary: Origin</h3>
<p>此时可以给多个域名控制 CORS,但此时假设有两个域名访问 <code>static.shanyue.tech</code> 的跨域资源</p>
<ol>
<li><code>foo.shanyue.tech</code>,响应头中返回 <code>Access-Control-Allow-Origin: foo.shanyue.tech</code></li>
<li><code>bar.shanyue.tech</code>,响应头中返回 <code>Access-Control-Allow-Origin: bar.shanyue.tech</code></li>
</ol>
<p>看起来一切正常,但如果中间有缓存怎么办?</p>
<ol>
<li><code>foo.shanyue.tech</code>,响应头中返回 <code>Access-Control-Allow-Origin: foo.shanyue.tech</code>,被 CDN 缓存</li>
<li><strong><code>bar.shanyue.tech</code>,因由缓存,响应头中返回 <code>Access-Control-Allow-Origin: foo.shanyue.tech</code>,跨域出现问题</strong></li>
</ol>
<p>此时,<code>Vary: Origin</code> 就上场了,代表为不同的 <code>Origin</code> 缓存不同的资源</p>
</div>
<div>
<div>
<h3 class="heading" data-id="heading-14">总结 (简要答案)</h3>
<p>CORS 如何指定多个域名?</p>
<p><strong>根据请求头中的 <code>Origin</code> 来设置响应头 <code>Access-Control-Allow-Origin</code></strong>,思路如下</p>
<ol>
<li>总是设置 <code>Vary: Origin</code>,避免 CDN 缓存破坏 CORS 配置</li>
<li>如果请求头不带有 <code>Origin</code>,证明未跨域,则不作任何处理</li>
<li>如果请求头带有 <code>Origin</code>,证明浏览器访问跨域,根据 <code>Origin</code> 设置相应的 <code>Access-Control-Allow-Origin: &lt;Origin&gt;</code></li>
</ol>
<p>使用伪代码实现如下</p>
</div>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获取 Origin 请求头</span>
const requestOrigin = ctx.get('Origin'<span style="color: rgba(0, 0, 0, 1)">);

ctx.set(</span>'Vary', 'Origin'<span style="color: rgba(0, 0, 0, 1)">)

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 如果没有,则跳过</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">requestOrigin) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> await next();
}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 设置响应头</span>
ctx.set('Access-Control-Allow-Origin', requestOrigin)</pre>
</div>
<p>&nbsp;</p>
</div>
</div>
</div><br><br>
来源:https://www.cnblogs.com/magicg/p/13468577.html
頁: [1]
查看完整版本: CORS 如果需要指定多个域名怎么办