ajax跨域產(chǎn)生原因(三個(gè)同時(shí)滿足會(huì)產(chǎn)生跨域問題):
1. 瀏覽器限制
2. 跨域請(qǐng)求了
3. XHR(XMLHttpRequest)請(qǐng)求
解決:
1. 解決瀏覽器限制:
2.不用XHR請(qǐng)求: 用JsonP(只支持get請(qǐng)求,后端需要修改)
3. 不跨域調(diào)用(最后修改的可能都是http服務(wù)器,但是不同域的http服務(wù)器)
* 被調(diào)用方修改,支持跨域(添加返回信息);
* 調(diào)用方修改,隱藏跨域
# Filter方案, Nginx
跨域請(qǐng)求,會(huì)先看是否是簡(jiǎn)單請(qǐng)求,非簡(jiǎn)單請(qǐng)求會(huì)先檢查后調(diào)用
簡(jiǎn)單請(qǐng)求:
方法為GET, HEAD, POST
請(qǐng)求header里面:
無自定義頭;
Content-Type為以下幾種: text/plain, multipart/form-data, application/x-www-form-urlencoded
常見的 非簡(jiǎn)單 請(qǐng)求:
put, delete方法的ajax請(qǐng)求
發(fā)送json格式的ajax請(qǐng)求
帶自定義頭的ajax請(qǐng)求
nginx:
啟動(dòng): start nginx
nginx -s stop 快速關(guān)機(jī)
nginx -s quit 優(yōu)雅的關(guān)機(jī)
nginx -s reload 更改配置,使用新配置啟動(dòng)新工作進(jìn)程烁焙,正常關(guān)閉舊工作進(jìn)程
nginx -s reopen 重新打開日志文件
查看進(jìn)程: tasklist /fi "imagename eq nginx.exe"
后臺(tái)返回值
callbackfunction({"name":"wwwwwwwwwwww"});
@RequestMapping("/gateway/data")
public @ResponseBody String gatewayData(ModelMap model, HttpServletRequest request, HttpServletResponse response) {
Map<String, Object> result = fundHistoryService.fundsAmountHomePage();
Map<String, Object> map = new HashMap<String, Object>();
map.put("fundInvestsum", ArithmeticUtil.divStrRoundDown(result.get("tradeSum")+"","10000", 0));
map.put("openAccountsum", result.get("openAccountAllsum"));
map.put("companyAccountsum",2718);
JSONObject jsonObject = JSONObject.fromObject(map);
return request.getParameter("callback")+"("+jsonObject.toString()+")";
}
1. 通過script標(biāo)簽引用,寫死你需要的src的url地址
<script>
var callbackfunction = function(data) {
console.log('我是跨域請(qǐng)求來的數(shù)據(jù)-->' + data.name);
};
</script>
<script src="[http://i2.mediapower.mobi/adpower/vm/Bora/js/test.js?callback=callbackfunction](http://i2.mediapower.mobi/adpower/vm/Bora/js/test.js?callback=callbackfunction)"></script>
2. 動(dòng)態(tài)創(chuàng)建script,來調(diào)用
function handleResponse(data){
console.log('The responsed data is: '+data);
$('.companyAccountsum').html(data.companyAccountsum);
$('.fundInvestsum').html(data.fundInvestsum);
}
var script = document.createElement('script');
//script.src = 'http://127.0.0.1:8081/yilucaifu/org/gateway/data.html?callback=handleResponse';
script.src = 'https://www.yilucaifu.com/org/gateway/data.html?callback=handleResponse';
document.body.insertBefore(script, document.body.firstChild);
3. JQuery的ajax,get方式
$(function(){
$.ajax({
async: false,
type: "GET",
dataType: 'jsonp',
jsonp: 'callback',
jsonpCallback: 'callbackfunction',
url: "http://i2.mediapower.mobi/adpower/vm/Bora/js/test.js",
data: "",
timeout: 3000,
contentType: "application/json;utf-8",
success: function(msg) {
console.log(msg);
}
});
})
$.getJSON(url + "?callback=?", data, function(data) {
}
4. web sockets
web sockets是一種瀏覽器的API爆捞,它的目標(biāo)是在一個(gè)單獨(dú)的持久連接上提供全雙工、雙向通信勾拉。(同源策略對(duì)web sockets不適用)
web sockets原理:在JS創(chuàng)建了web socket之后煮甥,會(huì)有一個(gè)HTTP請(qǐng)求發(fā)送到瀏覽器以發(fā)起連接。取得服務(wù)器響應(yīng)后藕赞,建立的連接會(huì)使用HTTP升級(jí)從HTTP協(xié)議交換為web sockt協(xié)議成肘。
只有在支持web socket協(xié)議的服務(wù)器上才能正常工作。
var socket = new WebSockt('ws://www.baidu.com');//http->ws; https->wss
socket.send('hello WebSockt');
socket.onmessage = function(event){
var data = event.data;
}
//Spring注解
@CrossOrigin
//過濾器
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletResponse res = (HttpServletResponse) response;
HttpServletRequest req = (HttpServletRequest) request;
String origin = req.getHeader("Origin");
if(!StringUtils.isEmpty(origin)) {
res.addHeader("Access-Control-Allow-Origin", origin);//帶cookie這里不能用*
}
res.addHeader("Access-Control-Allow-Methods", "*");
String headers = req.getHeader("Access-Control-Request-Headers");
if(!StringUtils.isEmpty(headers)) {//這里是可以直接寫*的
res.addHeader("Access-Control-Allow-Headers", headers);//發(fā)送json參數(shù)請(qǐng)求
}
res.addHeader("Access-Control-Max-Age", "3600");//預(yù)檢命令緩存時(shí)間 秒
res.addHeader("Access-Control-Allow-Credentials", "true");//帶cookie
chain.doFilter(request, response);
}
//前端代理 webpack.dev.config.js
config.devServer = {
noInfo: true,
hot: true,
inline: true,
outputPath: path.join(__dirname, 'dist'),
proxy: {
'/ma-contract': {
target: 'http://127.0.0.1:9999',
secure: false,
changeOrigin: true,
host: '127.0.0.1'
}
}
//Nginx代理
server{
listen 80;
server_name a.com;
location / {
proxy_pass http://localhost:8081;
}
location /ajaxserver{
proxy_pass http://localhost:8080/ajax;
}
}
server{
listen 80;
server_name b.com;
location /{
proxy_pass http://localhost:8080;
add_header Access-Control-Allow-Methods *;
add_header Access-Control-Max-Age 3600;
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Headers $http_access_control_request_headers;
if ($request_method = OPTIONS){
return 200;
}
}
}
//前端Ajax請(qǐng)求
/* $.ajax({
url : base + "/get1",
type: "get",
dataType : "jsonp",
success:function(json){
console.log(json);
}
}); */
/* $.ajax({//貴金所省份跨域請(qǐng)求
url : "https://mibaoapi.hseb.com.cn/bankbranch/getProveniences.json",
type: "get",
dataType : "jsonp",
success:function(json){
console.log(json);
}
}); */
$.getJSON(base+"/get1").then(function(result){//簡(jiǎn)單請(qǐng)求
console.log(result);
});
$.ajax({//json格式請(qǐng)求
url : base + "/postJson",
type: "post",
contentType:"application/json;charset=utf-8",
data:JSON.stringify({name:"jack"}),
success:function(json){
console.log(json);
}
});
$.ajax({//帶cookie的請(qǐng)求, 瀏覽器添加cookie: document.cookie = "jsession=jack"
url : base + "/getCookie",
type: "get",
xhrFields:{
withCredentials:true
},
success:function(json){
console.log(json);
}
});
$.ajax({//帶自定義頭
url : base + "/getHeader",
type: "get",
headers:{
"header1":"jack1"
},
beforeSend:function(xhr){
xhr.setRequestHeader("header2","rose")
},
success:function(json){
console.log(json);
}
});