You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
XMLHttpRequest cannot load http://www.server.com/server.PHP. No 'Access-Control-Allow-Origin' header is present on the requested resource.Origin 'http://www.client.com' is therefore not allowed access.
前言
什么是跨域?
这就说到需要提到浏览器的同源策略,注意:是浏览器的。
那么什么是同源策略?
同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。如果是两个网页的协议,域名,端口一致,则这两个页面有相同的源。
那么不遵守同源策略则会涉及到跨域问题。
补充:非同源的限制:
1. jsonp 方法
JSONP(JSON with Padding)是数据格式 JSON 的一种“使用模式”,可以让网页从别的网域要数据。另一个解决这个问题的新方法是跨来源资源共享。
由于同源策略,一般来说位于
server1.example.com
的网页无法与server2.example.com
的服务器沟通,而 HTML 的<script>
元素是一个例外。利用<script>
元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 数据,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的数据并不是 JSON,而是任意的 JavaScript,用 JavaScript 解释器运行而不是用 JSON 解析器解析。操作步骤:
1.在全局准备一个函数,用来接收数据
2.在请求的时候将准备好的函数的名字传递给后端,callback 后面的名字
3.后端返回函数的调用,并且将数据通过传递参数的形式传递过来
4.前端得到,处理数据
使用 jsonp
跨域的时候会报错,这里需要设置一个白名单,因为 jsonp 的跨域是敏感的,需要将 url 加入到可信任的白名单里面
自己封装 jsonp 请求方法
调用:
2. postMessage
这种方式通常用于获取嵌入页面中的第三方页面数据。一个页面发送消息,另一个页面判断来源并接收消息。
了解更多
3. 代理转发
日常开发中的
webpack proxy
就是通过代理的方式实现的跨域。基本行为:使用本地开发服务器接收客户端发送的请求后转发给其他服务器,然后再将目标服务器的响应返回到客户端。
其目的是为了便于开发者在开发模式下解决跨域问题(浏览器安全策略限制)
想要实现代理首先需要一个中间服务器,
webpack
中提供服务器的工具为webpack-dev-server
webpack-dev-server
webpack-dev-server
是webpack
官方推出的一款开发工具,将自动编译和自动刷新浏览器等一系列对开发友好的功能全部集成在了一起目的是为了提高开发者日常的开发效率,只适用在开发阶段
关于配置方面,在
webpack
配置对象属性中通过devServer
属性提供,如下:devServetr
里面proxy
则是关于代理的配置,该属性为对象的形式,对象中每一个属性就是一个代理的规则匹配属性的名称是需要被代理的请求路径前缀,一般为了辨别都会设置前缀为
/api
,值为对应的代理匹配规则,对应如下:工作原理
proxy
工作原理实质上是利用http-proxy-middleware
这个http
代理中间件,实现请求转发给其他服务器举个例子:
在开发阶段,本地地址为
http://localhost:3000
,该浏览器发送一个前缀带有/api
标识的请求到服务端获取数据,但响应这个请求的服务器只是将请求转发到另一台服务器中代理服务器
在开发阶段,
webpack-dev-server
会启动一个本地开发服务器,所以我们的应用在开发阶段是独立运行在localhost
的一个端口上,而后端服务又是运行在另外一个地址上所以在开发阶段中,由于浏览器同源策略的原因,当本地访问后端就会出现跨域请求的问题
通过设置
webpack proxy
实现代理请求后,相当于浏览器与服务端中添加一个代理者当本地发送请求的时候,代理服务器响应该请求,并将请求转发到目标服务器,目标服务器响应数据后再将数据返回给代理服务器,最终再由代理服务器将数据响应给本地
在代理服务器传递数据给本地浏览器的过程中,两者同源,并不存在跨域行为,这时候浏览器就能正常接收数据
注意:服务器与服务器之间请求数据并不会存在跨域行为,跨域行为是浏览器安全策略限制
4. CORS 跨域
CORS 是一个 W3C 标准,全称是"跨域资源共享"(Cross-origin resource sharing)。出于安全原因,浏览器限制从脚本内发起的跨源 HTTP 请求。 例如,XMLHttpRequest 和 Fetch API 遵循同源策略。
而跨域资源共享它允许浏览器向跨源服务器,发出
XMLHttpRequest
请求,从而克服了AJAX
只能同源使用的限制。而且比 JSONP 方法更为强大 ,支持所有类型的HTTP
请求。服务端设置
Access-Control-Allow-Origin
就可以开启 CORS。 该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。凡是不同时满足上面两个条件,就属于非简单请求。浏览器对这两种请求的处理,是不一样的
本文只讨论了简单请求的实现步骤
对于简单请求,浏览器发现这次跨源 AJAX 请求是简单请求,就自动在头信息之中,添加一个 Origin 字段。如下:
上面的头信息中,
Origin
字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。如果在服务端不被允许,直接使用 ajax 访问,会有以下错误:如果
Origin
指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段:1.Access-Control-Allow-Origin
该字段是必须的。它的值要么是请求时 Origin 字段的值,要么是一个
*
,表示接受任意域名的请求。2.Access-Control-Allow-Credentials
该字段可选。它的值是一个布尔值,表示是否允许发送 Cookie。默认情况下,Cookie 不包括在 CORS 请求之中。设为 true,即表示服务器明确许可,Cookie 可以包含在请求中,一起发给服务器。这个值也只能设为 true,如果服务器不要浏览器发送 Cookie,删除该字段即可。
3.Access-Control-Expose-Headers
该字段可选。CORS 请求时,XMLHttpRequest 对象的 getResponseHeader()方法只能拿到 6 个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在 Access-Control-Expose-Headers 里面指定。上面的例子指定,getResponseHeader('FooBar')可以返回 FooBar 字段的值。
实现一个使用 CORS 的跨域:
本地设置目录情况如下
前端
php
参考
The text was updated successfully, but these errors were encountered: