针对【error】No'Access-Control-Allow-Origin'跨域问题和跨域请求origin为null这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展Access-Cont
针对【error】No 'Access-Control-Allow-Origin' 跨域问题和跨域请求origin为null这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展Access-Control-Allow-Origin 与 Ajax 跨域、Access-Control-Allow-Origin 标头如何工作? - How does Access-Control-Allow-Origin header work?、Access-Control-Allow-Origin 跨域问题、Access-Control-Allow-Origin 跨域问题 SpringMVC解决 与 前端JS Webpack解决等相关知识,希望可以帮助到你。
本文目录一览:- 【error】No 'Access-Control-Allow-Origin' 跨域问题(跨域请求origin为null)
- Access-Control-Allow-Origin 与 Ajax 跨域
- Access-Control-Allow-Origin 标头如何工作? - How does Access-Control-Allow-Origin header work?
- Access-Control-Allow-Origin 跨域问题
- Access-Control-Allow-Origin 跨域问题 SpringMVC解决 与 前端JS Webpack解决
【error】No 'Access-Control-Allow-Origin' 跨域问题(跨域请求origin为null)
ajax报错:
XMLHttpRequest cannot load http://...... No ''Access-Control-Allow-Origin'' header is present on the requested resource. Origin ''null'' is therefore not allowed access.
跨域问题处理方式:dataType:"jsonp"
------------补充-------------------------------------------------------------------------------------------------
详见:http://kb.cnblogs.com/page/139725/
摘录:
用JSON(JavaScript Object Notation)来传数据,靠JSONP(JSON with Padding)来跨域。
因为src中的url文件都是可以实现跨域,而且json是js原生支持的,所以把json封装到js文件中来实现跨域。为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本。
Access-Control-Allow-Origin 与 Ajax 跨域
问题
在某域名下使用 Ajax 向另一个域名下的页面请求数据,会遇到跨域问题。另一个域名必须在 response 中添加 Access-Control-Allow-Origin
的 header,才能让前者成功拿到数据。
这句话对吗?如果对,那么流程是什么样的?
跨域
怎样才能算跨域?协议,域名,端口都必须相同,才算在同一个域。
参考:
- Are different ports on the same server considered cross-domain? (Ajax-wise)
- 同事李栋的博客:跨源资源共享
当跨域访问时,浏览器会发请求吗
这是真正困扰我们的问题,因为我们不清楚浏览器会怎么做。它会不会检查到你要请求的地址不是同一个域的,直接就禁止了呢?
我在 jsbin 上 做了一个试验 ,使用 Chrome 打开。当点击 “Run with Js” 时,控制台上会打出:
XMLHttpRequest cannot load http://google.com/. No ''Access-Control-Allow-Origin'' header is present on the requested resource. Origin ''http://run.jsbin.io'' is therefore not allowed access.
但开发者工具的”Network” 栏并没有任何记录。它到底发请求了没?
我又使用 python -m SimpleHTTPServer
在本地创建了一个小服务器,然后把地址改成它,结果发现在 python 这边的确打印出请求来了,可见浏览器的确发出了请求。
Access-Control-Allow-Origin
现在该 Access-Control-Allow-Origin
出场了。只有当目标页面的 response 中,包含了 Access-Control-Allow-Origin
这个 header,并且它的值里有我们自己的域名时,浏览器才允许我们拿到它页面的数据进行下一步处理。如:
Access-Control-Allow-Origin: http://run.jsbin.io
如果它的值设为 *
,则表示谁都可以用:
Access-Control-Allow-Origin: *
没错,在产品环境中,没人会用 *
你可以阅读下面这篇文章了解更多,并可找到其中的”Run Sample” 链接,实际体验一下:
http://www.html5rocks.com/en/tutorials/cors/
public HttpResponseMessage Get(string fatherId)
{
string str = JsonConvert.SerializeObject(GetAleCategorysByFid(fatherId), Formatting.Indented);
HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(str, Encoding.GetEncoding("UTF-8"), "application/json") };
result.Headers.Add("Access-Control-Allow-Origin", "*");
return result;
}
Access-Control-Allow-Origin 标头如何工作? - How does Access-Control-Allow-Origin header work?
问题:
Apparently, I have completely misunderstood its semantics. 显然,我完全误解了它的语义。 I thought of something like this: 我想到了这样的事情:
- A client downloads javascript code MyCode.js from http://siteA - the origin . 客户端从 http://siteA- origin 下载 javascript 代码 MyCode.js。
- The response header of MyCode.js contains Access-Control-Allow-Origin: http://siteB , which I thought meant that MyCode.js was allowed to make cross-origin references to the site B. MyCode.js 的响应标头包含 Access-Control-Allow-Origin:http:// siteB ,我认为这意味着 MyCode.js 被允许对站点 B 进行跨域引用。
- The client triggers some functionality of MyCode.js, which in turn make requests to http://siteB, which should be fine, despite being cross-origin requests. 客户端触发了 MyCode.js 的某些功能,该功能继而向 http://siteB 发出了请求,尽管这是跨域请求,但仍然可以。
Well, I am wrong. 好吧,我错了。 It does not work like this at all. 它根本不像这样工作。 So, I have read Cross-origin resource sharing and attempted to read Cross-Origin Resource Sharing in w3c recommendation 因此,我阅读了跨域资源共享,并尝试阅读 w3c 建议中的跨域资源共享
One thing is sure - I still do not understand how am I supposed to use this header. 可以确定的一件事 - 我仍然不明白我应该如何使用此标头。
I have full control of both site A and site B. How do I enable the javascript code downloaded from the site A to access resources on the site B using this header? 我对站点 A 和站点 B 都拥有完全控制权。如何使用此标头使从站点 A 下载的 javascript 代码能够访问站点 B 上的资源?
PS 聚苯乙烯
I do not want to utilize JSONP. 我不想利用 JSONP。
解决方案:
参考一: https://stackoom.com/question/id4F/Access-Control-Allow-Origin 标头如何工作参考二: https://oldbug.net/q/id4F/How-does-Access-Control-Allow-Origin-header-work
Access-Control-Allow-Origin 跨域问题
跨域配置逻辑说明
- 在 springboot 启动时,添加允许跨域的相关配置。
- 在 spring 收到请求后,会在跨域配置的列表中,匹配相应的 host 地址和 uri,如果存在相应的 host 地址和 uri,就在 response 中添加允许跨域的 header
Access-Control-Allow-Origin:http://127.0.0.1:8080
- 当浏览器收到上面的 header 时,就会允许跨域请求
-
Access-Control-Allow-Credentials
响应头表示,是否可以将对请求的响应暴露给页面。返回 true 则可以,其他值均不可以。https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Access-Control-Allow-Credential
Spring boot 配置代码:
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/task/rest/getUnReadMessageNumber")//允许跨域的uri
.allowedOrigins("*") //允许跨域的请求host
.allowedMethods("GET", "POST") //允许跨域的请求方式
.allowedHeaders("*") //允许跨域的header
.allowCredentials(true) //是否有资格把响应内容,暴露到页面
.maxAge(72000L); //token时长
}
}
允许跨域例子:
Access-Control-Allow-Origin 跨域问题 SpringMVC解决 与 前端JS Webpack解决
跨域问题 是针对ajax的一种限制
跨域:浏览器对于JS的同源策略的限制。
以下情况都属于跨域:
域名不同 如: www.jd.com www.taobao.com
域名相同,端口不同 如: www.taobao.com:8081 www.taobao.com:8082
二级域名不同 如: 3c.tmall.com chaoshi.tmall.com
http和https也属于跨域
解决跨域问题的方案
目前比较常用的跨域解决方案有3种:
-
Jsonp
最早的解决方案,利用script标签可以跨域的原理实现。 限制:需要服务的支持 ; 只能发起GET请求
-
nginx反向代理
思路是:利用nginx把跨域反向代理为不跨域,支持各种请求方式 缺点:需要在nginx进行额外配置,语义不清晰
-
CORS
规范化的跨域请求解决方案,安全可靠。
优势:在服务端进行控制是否允许跨域,可自定义规则 ; 支持各种请求方式
缺点: 会产生额外的请求
*****因为我们将采用CORS的方式解决,故重点介绍一下它如何来处理!!!*****
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest
请求,从而克服了AJAX只能同源使用的限制。
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
-
浏览器端:目前,所有浏览器都支持该功能(IE10以下不行)。整个CORS通信过程,都是浏览器自动完成,不需要用户参与。
-
服务端:CORS通信与AJAX没有任何差别,因此你不需要改变以前的业务逻辑。浏览器会在请求中携带一些头信息,我们需要以此判断是否允许其跨域,然后在响应头中加入一些信息即可。这一般通过过滤器完成即可。
浏览器会将ajax请求分为两类,其处理方案略有差异:简单请求、特殊请求
简单请求
只要同时满足以下两大条件,就属于简单请求。:
(1) 请求方法是以下三种方法之一:HEAD GET POST
(2)HTTP的头信息不超出以下几种字段: Accept Accept-Language Content-Language Last-Event-ID Content-Type:只限于三个值application/x-www-form-urlencoded
、multipart/form-data
、text/plain
当浏览器发现发起的ajax请求是简单请求时,会在请求头中携带一个字段:Origin
Origin中会指出当前请求属于哪个域(协议+域名+端口)。服务会根据这个值决定是否允许其跨域。
如果服务器允许跨域,需要在返回的响应头中携带下面信息:
Access-Control-Allow-Origin: http://yangw.com
Access-Control-Allow-Credentials: true
Content-Type: text/html; charset=utf-8
Access-Control-Allow-Origin:可接受的域,是一个具体域名或者*(代表任意域名)
Access-Control-Allow-Credentials:是否允许携带cookie,默认情况下,cors不会携带cookie,除非这个值是true
要想操作cookie,需要满足3个条件:
服务的响应头中需要携带Access-Control-Allow-Credentials并且为true。
浏览器发起ajax需要指定withCredentials 为true
响应头中的Access-Control-Allow-Origin一定不能为*,必须是指定的域名
特殊请求
不符合简单请求的条件,会被浏览器判定为特殊请求,,例如请求方式为PUT。
特殊请求会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest
请求,否则就报错。
与简单请求相比,除了Origin以外,多了两个头:
Access-Control-Request-Method: 接下来会用到的请求方式,比如PUT
Access-Control-Request-Headers: 会额外用到的头信息
Access-Control-Max-Age:本次许可的有效时长,单位是秒,过期之前的ajax请求就无需再次进行预检了(让它默认,不用处理)
我们只要解决了复杂清醒,简单情形自然包含了!
解决方式1:后端JAVA
我们用Java框架SpringMVC实现: 由于我这里是一个Spring Cloud项目,故写了个过滤器放在了网关里面统一处理
解决方式2--只在前端webpack-dev-server:
webpack配置中主要的参数说明
2.1 ‘/api’
捕获API的标志,如果API中有这个字符串,那么就开始匹配代理,
比如API请求/api/users, 会被代理到请求 http://www.baidu.com/api/users 。
2.2 target
代理的API地址,就是需要跨域的API地址。
地址可以是域名,如:http://www.baidu.com
也可以是IP地址:http://127.0.0.1:3000
如果是域名需要额外添加一个参数changeOrigin: true,否则会代理失败。
2.3 pathRewrite
路径重写,也就是说会修改最终请求的API路径。
比如访问的API路径:/api/users,
设置pathRewrite: {’^/api’ : ‘’},后,
最终代理访问的路径:http://www.baidu.com/users,
这个参数的目的是给代理命名后,在访问时把命名删除掉。
2.4 changeOrigin
这个参数可以让target参数是域名。
2.5 secure
secure: false,不检查安全问题。
设置后,可以接受运行在 HTTPS 上,可以使用无效证书的后端服务器
2.6 其他参数配置查看http-proxy-middleware文档
其他的配置参数等信息,可以查看这里:https://github.com/chimurai/h…
*********************以上两种解决方式任选其一均可**************
关于环境,我还在hosts中配置了域名映射,使用了nginx帮我反向代理
可以参考我上一篇博文 https://www.cnblogs.com/yangw/p/11947752.html
关于【error】No 'Access-Control-Allow-Origin' 跨域问题和跨域请求origin为null的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于Access-Control-Allow-Origin 与 Ajax 跨域、Access-Control-Allow-Origin 标头如何工作? - How does Access-Control-Allow-Origin header work?、Access-Control-Allow-Origin 跨域问题、Access-Control-Allow-Origin 跨域问题 SpringMVC解决 与 前端JS Webpack解决的相关知识,请在本站寻找。
本文标签: