Charles 的使用与 CORS 跨域

Charles_icon

问题的出现

在开发时,遇到了跨域的问题。具体情况是:

  • 运行 npm run dev 来开发项目,本地 Node 服务器开启在 8080 端口;
  • 在浏览器通过地址:(http://127.0.0.1:8000)访问页面
  • 通过 AJAX 请求调测试服务器的后端接口,地址为:(http://managerdev.offerhk.com)

之前的解决方案是直接安装 Chrome 插件:Allow-Control-Allow-Origin: * 来解除 Chrome 的跨域机制。

再次理解什么是跨域

浏览器的同源策略(Same Origin Policy)是浏览器出于安全方面的考虑,只允许与本域下的接口交互。不同源的客户端脚本在没有明确授权的情况下,不能读写对方的资源。

  • 同协议:如都是 http 或者 https
  • 同域名:如都是 http://example.com/ahttp://example.com/b
  • 同端口:如都是 80 端口

CORS 实现跨域

当你使用 XMLHttpRequest 发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头 Origin。后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin; 浏览器判断该相应头中是否包含 Origin 的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。

Charles 的 Tools

  • Map 功能适合长期地将某一些请求重定向到另一个网络地址或本地文件。
  • Rewrite 功能适合对网络请求进行一些正则替换。
  • Breakpoints 功能适合做一些临时性的修改。

Rewrite 的使用

给 HTTP 增加头部信息 Access-Control-Allow-Origin:*

遇到小问题

在增加了头部信息 Access-Control-Allow-Origin:*后,发现仍然无法正常的跨域。浏览器提示 Request header field x-csrf-token is not allowed by Access-Control-Allow-Headers in preflight response.。这里的 x-csrf-token 是 Laravel 在返回的 HTML 的头部加的字段,目的为了防止 CSRF 攻击。前端需要把这个 x-csrf-token 字段在请求头带到后端以供校验。

javascript - Request header field X-CSRFToken is not allowed by Access-Control-Allow-Headers in preflight response - Stack Overflow

解决问题

在调试香不香港 App 跨域时,同上遇到这个的问题。分析了原因,是使用 axios 给请求头(Requrest Header)加了个 userId。我们应该使用 Rewrite 来修改返回头,给它增加Access-Control-Allow-Headers字段,值是我们自定义的字段(比如上面说的 userId)。在 Charles 中使用方式如图:

总结解决问题的要点

浏览器将 CORS 请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。在上面我遇到的问题的请求就是非简单请求。

非简单请求的CORS请求,会在正式通信之前,增加一次 HTTP 查询请求,称为"预检"请求(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词头信息字段。只有得到肯定答复,浏览器才会发出正式的 XMLHttpRequest 请求,否则就报错。

Map Remote/Local 的使用

Charles 与 Surge 配合使用

Charles 设置为系统代理(默认监听 8888 端口),设置 External Proxy Setting 把 HTTP/HTTPS 设置为 Surge 的监听端口。

参考链接