[http] 跨域说明

只是从http层角度说下跨域的问题,并不提供解决方法,解决方法在以前老的文章里写过

跨域

跨域的请求被拦截有两种可能:
1. 浏览器直接禁止发起跨域,例如在某些浏览器中HTTPS请求HTTP域请求不会发起;
2. 跨域请求发起了,但是返回结果被浏览器拦截,请求失败。

CORS

w3c协议
CORS是一种利用额外HTTP头部来允许用户代理跨域请求的技术,与传统跨域方式不同,CORS使得原本只允许调用同源资源的api(例如XMLHttpRequest与fetch)中进行跨域操作变得可能
XMLHttpRequest与fetch请求跨域资源时会默认使用CORS协议检查

CORS请求分为预检,正式发送两部分。测试库链接

预检

简单请求不发送预检请求
简单请求指:
1. 请求方法仅可为GET,HEAD或POST
2. 请求头部Content-Type仅可为text/plain,multipart/form-data或application/x-www-form-urlencoded

// 不触发预检
fetch(url).then(function(response) {
  console.log(response);
});
// 触发预检
fetch(url, {
  headers: {
    'Content-Type': 'text/json'
  }
}).then(function(response) {
  console.log(response);
});

预检中不会带上触发了预检的请求头部,req.headers['content-type']是无法获取到值的
用户代理(浏览器)在接收到预检请求回复后会根据返回结果判断,主要是根据ACAO等几个字段判断跨域请求是否可发起
因此,需要编写对应的options请求处理接口

router.options('/cors', (req, res) => {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); // 允许请求头带content-type属性
  res.send();
});

这样就可以通过预检

处理

预检通过后,浏览器会发送实际请求。
在最终的处理接口里也要加上ACAO等几项,否则用户代理也会认为跨域请求失败,不会将结果返回。具体内容参见mdn

router.get('/cors', (req, res, next) => {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Credentials', true);
    res.json(data);
  }
});

需要说明的是,无论是简单请求还是通过了预检的跨域请求,都会将数据提交到服务器上并进行修改,无论服务器返回值会不会造成用户代理认为这次跨域请求失败

常见错误

  1. 请求带cookie时,回复中的Access-Control-Allow-Origin不能是*且Access-Control-Allow-Credentials必须设置为true
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值