跨域是违反浏览器的同源协议进行请求。

同源策略: 两个 URL 有相同的协议头,主机,端口

CORS

跨源资源共享(Cross-Origin Resource Sharing,CORS)是一种机制,它使用额外的 HTTP 头来告诉浏览器,让在一个源头运行的 Web 应用程序访问来自不同源头的选定资源。当 Web 应用程序请求一个与自己的资源有不同来源(域、协议或端口)的资源时,它会执行一个跨源的 HTTP 请求。

简单请求和复杂请求

简单请求:浏览器会直接发出 CORS 请求,在头信息之中,增加一个 Origin 字段。简单请求方法必须是下列其中一种:

  • GET
  • HEAD
  • POST

复杂请求:首先通过 OPTIONS 方法向服务器上的资源发送一个”预请求”,服务端也需要返回”预回应”作为响应,以确定实际发送的请求安全。预请求实际上是对服务端的一种权限请求,只有当预请求成功返回,实际请求才开始执行。

响应头部

服务器为 CORS 规范定义的访问控制的响应头部。

  • Access-Control-Allow-Origin: <origin> | *
  • Access-Control-Allow-Headers: <header-name>[, <header-name>]*
  • Access-Control-Allow-Methods: <method>[, <method>]*
  • Access-Control-Allow-Credentials: true
  • Access-Control-Max-Age: <delta-seconds>
  • Access-Control-Expose-Headers: <header-name>[, <header-name>]*

示例 1

http
  .createServer((req, res) => {
    res.writeHead(200, {
      // 'Access-Control-Allow-Origin': '*', // 设置运行的访问来源
      'Access-Control-Allow-Origin': 'http://localhost:8080',
      'Access-Control-Allow-Method': 'GET', // 设置允许的访问方法
    });
    res.end();
  })
  .listen(7000);

HTML 属性 - crossorigin

crossorigin 是一个 HTML 媒体标签的属性,表示跨域的请求来源。对 <audio>,<img>,<link>,<script>, <video> 标签元素有效,允许元素进行 CORS 请求。

corsorigin 可以设置为:

  • anonymous
  • use-credentials
  • ''

非法值和空字符串都会被设置为 anonymous。

JSONP

JSONP 最大的特点就是简单适用,兼容性好,缺点是只支持 GET 请求,不支持 POST 请求。

原理是浏览器限制了 HTTP 的跨域,但没有限制 script 标签内容的跨域请求。

通过在网页通过添加一个 script 脚本,向服务器发送 JSON 数据。

示例 2

var express = require('express');
var app = express();

app.get('/', function (req, res) {
  res.jsonp('hello jsonp');
});

app.listen(7000);
<script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
<script type="text/javascript">
  $.getJSON('http://localhost:7000?callback=?', function (res) {
    console.log(res);
  });
</script>

参考链接