跨域请求方法

跨域

  1. 不同源的Ajax请求均为跨域, 即浏览器url和请求接口地址的协议+域名+端口中有一个不相同的Ajax请求
  2. 受浏览器的同源策略影响,浏览器会拒绝不同源的Ajax请求

注意:

  1. 不在浏览器发起http协议请求不受跨域影响
  2. 非http协议请求不受跨域影响.
同源策略
  • 是浏览器的基本安全策略,不能通过Ajax请求不同域的数据
  • 同源:协议+域名+端口相同
  • 解决:XSS、CSFR等攻击
为什么需要跨域请求

一个需求需要请求多个服务器的接口

跨域请求方式

1. jsonp

使用script标签进行发起get请求,因为script标签请求不受同源策影响,script标签的get请求不是Ajax请求。

  • 优点: 兼容性好
  • 缺点: 只能发起get请求,jsonp的错误处理机制没有XMLHttpRequst好
// 向服务器test.com发出请求,该请求的查询字符串有一个callback参数,用来指定回调函数的名字
<script src="http://test.com/data.php?callback=dosomething"></script>
 
// 处理服务器返回回调函数的数据
<script type="text/javascript">
function dosomething(res){
    console.log(res.data)
}
</script>
// 封装方法
function jsonp({url, params, callback}) {
  jsonp.cbId = jsonp.cbId || 1
  jsonp.callbacks = jsonp.callbacks || []
  jsonp.callbacks[jsonp.cbId] = callback

  let script = document.createElement('script')
  params['callback'] = `jsonp.callbacks[${jsonp.cbId}]`
  script.setAttribute('src', url + getParams(params))
  document.body.append(script)

  jsonp.cbId++
}

// 处理服务器返回回调函数的数据
function dosomething(res){
    console.log(res.data)
}
jsonp({
  url: "http://test.com/data.php?callback=dosomething",
  params: {id: 1},
  callback: dosomething
})
2. CORS 跨域资源共享

CORS 是W3C的一个官方方案,跨源Ajax请求的根本解决方法。

  • 普通跨域实现:服务器端设置Access-Control-Allow-Origin, 如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问
// 服务器
response.setHeader("Access-Control-Allow-Origin", "http://www.main.com"); // 指定地址可以访问 
response.setHeader("Access-Control-Allow-Origin", "*"); // 允许所有域访问
  • 带cookie的跨域请求:前端需设置xhr.withCredentials = true,服务器端设置Access-Control-Allow-Origin
// 前端
let xhr = new XMLHttpRequest()
xhr.withCredentials = true // 前端设置是否带cookie

// 服务器
response.setHeader("Access-Control-Allow-Origin", "http://www.main.com"); 
response.setHeader("Access-Control-Allow-Credentials", "true");
3. postMessage

window.postMessage(mssage, targetOrigin) 是html5新引进的特性,可以用来向其他window对象发送消息,无论这个window对象属于同源或不同源。

window.postMessage(message, targetOrigin);
const openWindow = window.open('http://www.test.com', 'title')
openWindow.postMessage('the data', 'http://www.test.com')

// http://www.test.com 接受消息
window.addEventListener('message', function(e) {
  console.log(e.data) // 发送的数据
  console.log(e.source) // 消息发送的地址
  console.log(e.origin) // 消息发向的地址
})
4. websocket
  • 没有同源限制,客户端可以与任意服务器通信。
  • 协议标识符是 ws, 加密为 wss,如 ws://http://example.com:8080
  • 可以发送文本,也可以发送二进制数据
  • 建立在 TCP 协议之上
// 创建websocket实例
const ws = new WebSocket('ws://localhost:8080');

// 监听状态
switch (ws.readyState) {
  case WebSocket.CONNECTING:
    // do something
    break;
  case WebSocket.OPEN:
    // do something
    break;
  case WebSocket.CLOSING:
    // do something
    break;
  case WebSocket.CLOSED:
    // do something
    break;
  default:
    // this never happens
    break;
}

// 当连接成功后会触发 open 事件
ws.onopen = function () {
  // 发送信息到服务端
  ws.send('Hello Server!');
}

// 当连接关闭后会触发 close 事件
ws.onclose = function(event) {
  // handle close event
};

// 接受服务端的信息
ws.onmessage = function(event) {
  let data = event.data;
  // 处理数据
};

// 捕捉错误
ws.onerror = function(event) {
  // handle error event
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值