网站开发跨域问题解决方案

网站开发跨域问题解决方案

什么是跨域问题?
跨域问题,即浏览器报 Error: Access to XMLHttpRequest at ‘http://example1.com’ from origin ‘http://example2.com’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. 这个错误。
网站开发跨域问题解决方案
这是因为:

处于安全原因,浏览器会限制由脚本发起的 HTTP 请求,例如,XMLHttpRequest 和 Fetch API 都应遵循同源策略。这意味着一个 web app 只能请求与它本身同源的资源 API,除非一个不同源的 API 配置了正确的 CORS 头。
For security reasons, browsers restrict cross-origin HTTP requests initiated from scripts. For example, XMLHttpRequest and the Fetch API follow the same-origin policy. This means that a web application using those APIs can only request resources from the same origin the application was loaded from unless the response from other origins includes the right CORS headers. (Cross-Origin Resource Sharing (CORS) - MDN)

*同源:如果两个 URL 的 protocol、port 和 host 都相同的话,则称这两个 URL 是同源。

解决方案

  1. (仅开发环境下)修改浏览器安全策略
    跨域拦截是客户端浏览器的行为,为了开发的方便,开发者可以暂时屏蔽掉这一项安全策略。
    例如,<新版chrome浏览器设置允许跨域> --haorooms 中介绍了 手动重设 chrome 浏览器该配置的方法。
    此外,Moesif CORS 等浏览器插件也可实现同样的功能。
    网站开发跨域问题解决方案

当然,这样的方法只适用于开发环境,因为你作为开发者不应该干涉用户的安全配置。

  1. (仅开发环境下)webpack-dev-server 代理
    在使用 webpack-dev-server 的时候,可以通过在 webpack.config.js 中配置 proxy 实现跨域。即请求会指向 dev-server,由 dev-server 再向 target 做请求。这样对浏览器来说,前后端总是同源的,因为他们都在 dev-server 上。
    例如如下的配置:
    网站开发跨域问题解决方案

(可参考 devserver-proxy --webpack文档)

  1. 服务端反向代理(网关)
    服务端反向代理是解决跨域问题的最常见办法!大多数服务端框架都支持此功能,常见如 nginx(nginx HttpProxy模块)、Apache(Apache 反向代理指南)、Express(http-proxy-middleware)等。
    网站开发跨域问题解决方案

通过在服务端配置反向代理,对浏览器(客户端来说)页面和各种资源、API都是同源的。

  1. JSONP
    jsonp 是一种传统的处理跨域问题的方案,其原理是使用

网站开发跨域问题解决方案

它的缺点在于,一是只能获取数据,而不能向后端回传数据,二是请求得到的结果会被直接执行,可能会有安全风险。

  1. CORS
    CORS(Cross-Origin Resource Sharing)是对跨域问题的终极解决办法。它由一系列传输的HTTP头组成,这些HTTP头决定浏览器是否阻止前端 JavaScript 代码获取跨域请求的响应。

针对简单请求,浏览器会直接发出 CORS 请求,其头部会包含一个 Origin 字段。如果请求的源符合后端要求,那么返回的头中会包含 Access-Control-Allow-Origin, Access-Control-Allow-Credentials 等字段,可以被浏览器正常解析。

针对非简单请求,浏览器会先做一次 OPTIONS (预检)请求,在确认后端支持该 CORS 请求时再发出正式请求,否则正式请求不会被发出。

参考 阮一峰的网络日志:跨域资源共享 CORS 详解

  1. iframe
    可以在页面中以 iframe 的方式加载目标域下的页面,通过 postMessage 的方法请求该域下的数据,以此避免跨域问题。

  2. webSocket
    WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。基于 WebSocket 的通信不存在跨域问题。

上一篇:5.Appium的pc端实现手机端页面


下一篇:【Django】Django解决跨域问题