一步一步解决异步跨域请求CORS(跨域资源共享)报错

Access-Control-Allow-Origin

错误

Failed to load http://localhost:8081/request: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.

原因

No 'Access-Control-Allow-Origin' header这基本是跨域请求遇到的第一个错误。浏览器基于同源政策,它会禁止AJAX发起非同源请求,其中同源包括三同:协议相同(如http),域名相同以及端口相同。

CORS则是允许浏览器向跨源服务器发起请求。这需要服务器端支持。

解决

解决跨域请求的第一个问题就是在响应的头信息加上Access-Control-Allow-Origin。

指定域名

Access-Control-Allow-Origin: http://www.example.com

允许所有域名访问

Access-Control-Allow-Origin: *

Access-Control-Allow-Credentials

错误场景
考虑下一个登陆功能,进入登录页面,我们向服务器请求验证码,验证码存放在session里。用户输入登录信息以及验证码发起异步跨域请求登录,你会发现,每次验证都是验证码不正确。

原因

查看下验证码的http和验证登陆的http请求的响应头信息Set-Cookie,你会发现两次请求的SessionId是不相同的。

CORS请求默认不发送Cookie和HTTP认证信息,如果我们想让CORS保持会话,我们需要服务器和浏览器端支持。

服务器端需要添加Access-Control-Allow-Credentials响应头信息:

Access-Control-Allow-Credentials: true

浏览器端需要在AJAX请求添加withCredentials属性:

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

预检请求(preflight)

错误

Failed to load http://localhost:8081/auth.json: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.

原因

非简单请求的CORS请求(包括PUT,DELETE或Content-Type类型是application/json),浏览器会在正式请求前,增加一次HTTP的OPTIONS查询请求,称为预检请求。预检请求目的是为了检查正式请求的域名,头信息以及HTTP 请求方法是否符合要求。预检请求失败则不会发起正式请求。

如上面的错误提示,content-type没有在被允许的头信息里。

解决

使用Access-Control-Allow-Headers添加允许的头信息,如content-type

Access-Control-Allow-Headers:content-type

对于多个需要被允许的头部,使用逗号隔开,如:

Access-Control-Allow-Headers:x-requested-with,content-type

版权声明:著作权归作者所有。

相关推荐

一些有用的pandas代码片段

# 列出dataframe指定列的唯一值 df['Column Name'].unique() # 把列的数据类型转换为数字。如果有非数字值,则会出错。 pd.to_numeric(df['Column Name']) # 把列的数据类型转换为数字,如果非数字值,则会转换为NaN pd.to_numeric(df['Column Na

Nginx同一个域名配置多个项目

使用Nginx要在同一个域名下配置多个项目有两种方式:nginx按不同的目录分发给不同的项目启用二级域名,不同的项目分配不同的二级域名nginx按不同的目录分发给不同的项目在nginx的server节点配置server {     listen    80;     server_name example.c

使用ANDROID_ID唯一标识Android设备

使用Settings.Secure#ANDROID_ID 会返回每个用户唯一的64位hex字符串,它是在设备首次boot时生成。我们可以使用它来唯一标识Android设备。import android.provider.Settings.Secure; private String android_id = Secure.getStri

Git撤销最后一次提交

Git可以使用reset重置来撤销提交。方法一撤销最后一次提交git reset HEAD~1 执行后,状态重置为上一次提交,且撤回提交的文件的状态变回unstaged,即文件没有被git跟踪。示例$ git commit -m 'add test.html' [master ade6d7e] add&nbs

[译]Java 9:一步步迁移项目到Jigsaw(模块化)

Java 9出来了。 我们来试试一个简单的Spring项目。 为了使练习更具挑战性,我们还要尝试使用新的模块系统。 该项目只是一个使用Spring,JDBC和Shedlock的简单示例。1、阅读所有可用的文档和规格说明。 嗯,听起来很无聊。 跳过第一步。2、下载JDK并尝试运行该项目。 我们很幸运,我们所有的依赖只使用公共Jav

Angular4使用Rxjs5共享Http请求返回的结果数据

在使用Angular开发的单页面应用里,有时需要处理这种场景:使用http请求某个数据,数据请求成功后需要把数据更新到多个组件里。也就是说,有多个observer(观察者)对http请求数据返回的Observable订阅。getDta() {     return this.http.get('/dataUrl').map(res&nbs