来,跨个域看看 (CORS)

CORS 即跨资源共享,是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的 Web 应用被准许访问来自不一样源服务器上的指定的资源。 简单来讲,出于安全缘由,浏览器会限制从脚本内发起的跨域请求,如 XMLHttpRequest 和 Fetch。也就是说,在 Javascript 中,当咱们想发起一个跨域的 Ajax 请求,会受到浏览器的限制致使请求失败。javascript

举个例子: 在 http://mysite.com/index.html 中,发起一个 Ajax 请求到 http://api.yoursite.com/article/all/,会失败,若是打开控制台看日志,会看到相似以下的输出:html

Access to XMLHttpRequest at 'http://api.yoursite.com/article/all/' from origin 'http://mysite.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
复制代码

在如今开发常规 Web 项目的时候,即便在正式上线后使用统一域名访问项目,也很难说在开发和联调过程当中也使用统一域名,因此掌握跨域请求的处理仍是颇有必要的。前端

实现跨域请求的途径

跨域请求的处理方法除了 CORS 外,还有 代理服务器JSONPjava

代理服务器

一说到使用服务器的方式,咱们能够立刻想到一个流行的反向代理服务器 Nginx,的确,咱们可使用 Nginx 的 proxy_pass 指令实现代理的目的,但这种方法每每很不直观,且通常也须要前端同窗在本地搭建相关环境才能够运做,能够说是一个不怎么样的选择。nginx

除了 Nginx 外,前端的同窗可能会说如今不少流行的框架都集成有这样的功能,如 Vue.js 的 devServer,前端同窗能够在项目中编写熟悉的 Javascript 代码以实现请求的代理,最终实现跨域请求,方便联调,但也局限于开发时使用。django

JSONP

JSONP 是利用了 src 引用静态资源时不受跨域限制的机制,前端会先定义一个回调函数用来处理请求成功后的逻辑,并在请求服务端时告知服务端这个回调函数的名字,而服务端只须要把须要返回的数据按照 Javascript 的语法,放进回调函数中便可。 大概像这样子:编程

<!-- http://mysite.com/index.html -->
<script> function callback(data) { // 处理 data console.log(data) } </script>
<script src="http://api.yoursite.com/article/all/?callbackFunc=callback"></script>
复制代码

的确,JSONP 能够成功获取到数据,且回调函数也会被正确执行,但在使用 JSONP 以前,它的缺点你须要先了解:后端

  • 只能用 HTTP Get 请求;
  • 错误处理不完善,咱们很难对请求时发生的错误进行处理;
  • 安全问题;
  • 等等。

说实话,如今在开发项目时已经不多使用 JSONP 了,这里只是给同窗们了解了解。api

CORS

CORS 机制,容许 Web 应用服务器进行跨域访问控制,从而使跨域数据传输得以安全。跨域

这里以 Nginx 为例,看看要怎样才能作到跨域访问控制。 咱们来看看如何配置吧:

http {
  # 省略其余...
  server {
    listen 80;
    server_name api.yoursite.com;
    charset utf-8;
    location / {
      include /usr/local/nginx/conf/cors;
      // 省略其余...
    }
  }
}
复制代码

这样,咱们 http://api.yoursite.com/ 下的 API 就支持跨域请求了(不考虑程序代码有限制的状况)。

重点是 include /usr/local/nginx/conf/cors; ,下面来看看 cors 文件里面的内容吧:

cors

其核心的部分,是加入了 Access-Control-Allow-Origin HTTP 头,而其余部分的内容,则是更细粒度的控制,如不一样的请求方法也能够设置不一样的 HTTP 头达到控制的目的。 搭配 Nginx 的 location 指令,咱们则能够控制某些路径下才开启 CORS,以达到更细粒度的控制。

你们能够在 enable-cors.org/server_ngin… 得到 cors 文件的内容。这个文件内容只是一个范本,并非惟一的写法,你们在实际使用时按照需求自行修改便可。

若是你想更深刻了解 CORS 机制,能够访问 developer.mozilla.org/zh-CN/docs/…

不用 Nginx 行不行?

理解了 CORS 机制的原理的话,这种问题不在话下。

这个网址提供了不一样服务器、Web 框架、编程语言的实现方式,enable-cors.org/server.html…

忍不住吐槽,里面恰恰没有 Django 的实现方式,Django 的话,可使用 django-cors-headers,在使用 Django 开发后端时,前端也能愉快的发起跨域请求了。

选择 CORS

从技术的革新角度也好,从使用的便捷度也好,CORS 是一个更好的跨域请求的选择。只须要(通常是)后端人员配置好,前端能够不须要作任何额外的改变,就能够调用后端 API 了。这种方法,不管是开发时或是正式上线后,均可以使用,无需考虑过大的差别性问题。

尚未用过 CORS 的同窗,赶忙尝试一波吧。

相关文章
相关标签/搜索