跨域请求中OPTIONS请求的问题及解决方法进程经常会遇到跨域问题。网上也有解决办法。写这篇文章的时候,遇到了一个场景:做一个s系统的扩展,前端html和js放在s系统中,后端需要做一个单独的站点n.b.com。这会导致跨域问题。大多数时候,可以使用CORS解决方案来解决跨域问题。但这次我有点特别。前端是get请求,理论上没问题,但是请求头中要加两个自定义的headerGEThttp://localhost:8080/api/v1/usersAccept:*/*Content-Type:application/jsonAuthorization:token:21232f297a57a5a743894a0e4a801fc3Username:admin添加了两个自定义字段Authorization和Username请求时,看到网络中出现两条请求记录。第一个是OPTION请求状态码200,第二个是Myget请求状态码401可以由后端的CORS在这里处理。为什么还会这样。我们一般解决项目中的跨域问题。简单的说,我们会采用诸如使用ajax直接跨域访问等方案2、使用JsonP。在实际使用中,由于JsonP提交给服务器的URL长度限制为8000个字符,如果超过该长度会被浏览器拒绝,所以没有使用。对于第一种方案,后端需要做的工作是:接口允许跨域请求:header('Access-Control-Allow-Origin:*');//支持全域名访问,不安全,部署后需要限制ForR.comheader('Access-Control-Allow-Methods:POST,GET,OPTIONS,DELETE');//支持的httpactionheader('Access-Control-Allow-Headers:x-requested-with,content-type');//响应头,请根据需要添加。前端发起跨域请求:普通的$.ajax请求即可。我项目使用的vue全家桶axios发送的请求//请求拦截器service.interceptors.request.use(config=>{if(store.getters.token){config.headers['Authorization']=`token:${getToken()}`config.headers['Username']=`getUsername()`}returnconfig},error=>{//DosomethingwithrequesterrorPromise.reject(error)})但是,点击When说到一个问题,国内网站基本不讲,就是optionrequest问题。在正式跨域请求之前,浏览器会根据需要发起一次“PreFlight”(即Option请求),让服务器返回允许的方法(如get、post),以及Origin(source)跨域访问,或域),是否需要Credentials(认证信息):如果跨域请求是SimpleRequest(简单请求),则不会触发“PreFlight”。Mozilla对简单请求的要求是:以下三项必须全部成立:只有Get、Head、Post方法。除了浏览器自己在Http头上添加的信息(如Connection、User-Agent),开发者只能添加这几个:Accept、Accept-Language、Content-Type、。...Content-Type只能取这些值:application/x-www-form-urlencodedmultipart/form-datatext/plainXHR对象有三种类型的HTTP跨域请求:简单请求、预检请求和预检认证请求。简单请求不需要发送OPTIONS嗅探请求,只能发送简单的GET、HEAD或POST请求,不能自定义HTTPHeaders。Preflighted请求和认证请求,XHR会先发送一个OPTIONS嗅探请求,然后XHR会根据OPTIONS请求返回的Access-Control-*头信息判断是否可以访问指定站点,最后决定是否发送实际请求信息。那么我的get请求呢?原来OPTIOINS请求的原因是:customHeaders头信息。浏览器会向服务器发送OPTIONS请求,查看服务器返回的“Access-Control-Allow-Headers”是否有自定义的头字段。因为我之前没有返回自定义字段,所以默认是不允许的,导致客户端无法获取到数据。这种情况下,如果后端是python,那么fromcorsheaders.defaultsimportdefault_headersCORS_ALLOW_HEADERS=default_headers+('Authorization,Username')如果你在前端使用vue全家桶,那么可以这样做module.exports={NODE_ENV:'"development"',ENV_CONFIG:'"dev"',BASE_API:'"/proxy"'}'/proxy':{target:'http://jupiter.dev.grdoc.org/',changeOrigin:true,pathRewrite:{'^/proxy':'/'},sesure:false}如果开发环境这么搞,应该不算跨域。我是闪豆我的gitHub
