什么是跨域?
跨域问题是因为浏览器的同源策略造成的,是浏览器对javascript 实施的安全策略。使得浏览器不能执行网站请求。
当我们访问api接口的时候,在浏览器上会出现
Access to XMLHttpRequest at 'http://localhost:7002/test' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
同源策略:
URL | 是否允许通信 |
---|---|
同一域名 | 允许 |
同一域名,不同端口 | 不允许 |
同一域名,不同协议 | 不允许 |
域名和域名对应的IP | 不允许 |
主域名和子域名 | 不允许 |
不同域名 | 不允许 |
怎样解决跨域问题
1.JSONP
script 标签的src 属性在同源策略问题上就不会遇到跨域的问题,因此可以使用这种请求方式来实现http请求.
前端代码:
function createJsonp(url,callback) {
let jsonp = document.createElement('script');
let data;
jsonp.type = "text/javascript";
jsonp.src = `${url}?callback=jsonCallback`;
document.getElementsByTagName('head')[0].appendChild(jsonp);
setTimeout(() => {
document.getElementsByTagName('head')[0].removeChild(jsonp)
}, 500);
window.jsonCallback = (result) => {
callback(result)
}
}
createJsonp('http://localhost:7002/test',function(data){
console.log(data)
}) ;
前端可以通过回调函数获取需要的数据
后端代码:
async test(){
const {ctx} =this;
const cb = ctx.queries.callback;
ctx.set('Content-Type','application/javascript;charset=utf-8')
let data = {
name:'name1',
age:20
}
ctx.body = cb+`(${JSON.stringify(data)})`
}
2.使用Nginx 反向代理
# 第一种
server {
listen 8080;
server_name 需要代理的服务地址(localhost)
location / {
proxy_pass 转发到服务地址(http://localhost:7002);
}
}
#第二种
server
{
listen 80;
server_name 需要代理的服务地址(localhost);
location /ok {
proxy_pass http://localhost:7002;
# 允许跨域的方法,*代表所有(GET,POST,DELETE,PUT...)
add_header Access-Control-Allow-Methods *;
# 指定本次预检请求的有效期,单位为秒,,在此期间不用发出另一条预检请求。
add_header Access-Control-Max-Age 3600;
# 带cookie请求需要加上这个字段,并设置为true
add_header Access-Control-Allow-Credentials true;
# 表示允许这个域跨域调用(客户端发送请求的域名和端口)
# $http_origin动态获取请求客户端请求的域 不用*的原因是带cookie的请求不支持*号
add_header Access-Control-Allow-Origin $http_origin;
# 表示请求头的字段 动态获取
add_header Access-Control-Allow-Headers
$http_access_control_request_headers;
# OPTIONS预检命令,预检命令通过时才发送请求
# 检查请求的类型是不是预检命令
if ($request_method = OPTIONS){
return 200;
}
}
}
3.CORS
Cors 是使用自定义的HTTP头部让浏览器与服务器进行数据交换,从而决定请求响应是否应该成功。
需要在后台服务上进行配置
例如在egg.js中使用:
需要下载安装egg-cors 插件(略过)
// 配置的参数
{String|Function(ctx)} origin `Access-Control-Allow-Origin`, default is request Origin header
{String|Array} allowMethods `Access-Control-Allow-Methods`, default is 'GET,HEAD,PUT,POST,DELETE,PATCH'
{String|Array} exposeHeaders `Access-Control-Expose-Headers`
{String|Array} allowHeaders `Access-Control-Allow-Headers`
{String|Number} maxAge `Access-Control-Max-Age` in seconds
{Boolean} credentials `Access-Control-Allow-Credentials`
{Boolean} keepHeadersOnError Add set headers to `err.header` if an error is thrown
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。