前后端分离架构离不开跨域请求,ext也不例外,ext封装了jsonp模块,相关的有 jsonpStore 和 jsonpProxy
原理
如果有这个请求
Ext.data.JsonP.request({
url : 'foo.php'
});
ext会在头部创建一个 script 标签请求 foo.php 路径下的资源(get方法),对应的路径foo.php?callback=Ext.data.JsonP.callback1
服务器请求获取对应的 callback 参数返回对应的函数执行字符串
Ext.data.JsonP.callback1({"foo":"bar"});
服务器请求处理
<?php
$data = array('foo' => 'bar');
if (!empty($_REQUEST['callback'])) {
header('Content-Type: application/javascript');
echo $_REQUEST['callback'] . '(';
}
echo json_encode($data);
if (!empty($_REQUEST['callback']) {
echo ');';
}
?>
JsonPStore
JsonpStore和普通的store差不多,请求方式是用上面的原理来请求数据,配置JsonPStore
Ext.define("extjsapp2.store.Question", {
extend: "Ext.data.JsonPStore",
alias: "store.question",
storeId: "questionStore",
proxy: {
url: "http://localhost:3000/api/questions"
},
fields: ["title"],
autoLoad: true
})
extjs会生成对应当路径http://localhost:3000/api/questions?_dc=1496547546379&page=1&start=0&limit=25&callback=Ext.data.JsonP.callback1
请求服务器资源
每次请求附加参数extraParams
proxy: {
url: "http://localhost:3000/api/questions",
extraParams: {
token: "kalsjdaieroqwnlnlk"
},
},
自己测试了一遍,返回数据是数组可以正常渲染,但是嵌套子对象设置 root/rootProperty;都无法获取对应点数组,应该是个bug
Store + Proxy
上面的不能设置 root 来指定数组渲染数据,用正常的store和proxy来实现jsonp,可以获取嵌套的数据,发现什么问题
Ext.define("extjsapp2.store.Question", {
extend: "Ext.data.Store",
alias: "store.question",
storeId: "questionStore",
proxy: {
type: 'jsonp',
url: "http://localhost:3000/api/questions",
extraParams: {
curPage: 1,
token: "kalsjdaieroqwnlnlk"
},
reader: {
type: 'json',
rootProperty: 'list', // 子对象数组
}
},
fields: ["title"],
autoLoad: true,
listeners: {
load: function (store, records, successful, eOpts) {
console.log(records)
}
}
})
jsonp request
在处理程序中请求jsonp数据,例如点击按钮获取
Ext.data.JsonP.request({
url: 'http://localhost:3000/api/questions',
callbackKey: 'callback',
params: {
key: '23f6a0ab24185952101705',
},
success: function(result, request) {
console.log(result);
}
});
post跨域请求
跨站请求另一种方式在服务端实现,Cross-Origin Resource Sharing(跨域资源共享)是一种允许当前域(origin)的资源(比如html/js/web service)被其他域(origin)的脚本请求访问的机制。
当使用XMLHttpRequest发送请求时,浏览器如果发现违反了同源策略就会自动加上一个请求头:origin,后端在接受到请求后确定响应后会在Response Headers中加入一个属性:Access-Control-Allow-Origin,值就是发起请求的源地址(http://127.0.0.1:8888),浏览器得到响应会进行判断Access-Control-Allow-Origin的值是否和当前的地址相同,只有匹配成功后才进行响应处理。
在服务器返回的头部设置"Access-Control-Allow-Origin":'*'就可以实现跨域请求
extjs官方推荐的使用jsonp,使用 Ext.Ajax.request 也可以来实现跨域请求
Ext.Ajax.request({
url: 'http://www.cctv.com/datas',
timeout: 3000,
method: "POST",
cros: true,
useDefaultXhrHeader: false,
params: {
params: JSON.stringify({
from: 0,
to: 4294967295
})
},
paramsAsJson: true,
success: function (data) {}
})