Cors& Ajax

Cors技术,涉及服务器和浏览器。经过测试,只有服务器授权的站点才能资源共享,至少需要Access-Control-Allow-Origin授权,

授权为*时,withCredentials只能是false,Ajax每次都相当于独立的请求,与前后请求无关。

Access-Control-Allow-Origin授权指定站点,withCredentials设置为true时,Ajax几次请求相当于一个会话里。

下面例子模拟了一个会话过程。

服务端:

跨域,可以写一个Filter,放到Filter chain最前面。

if (crossDomain)

{

String origin = req.getHeader("Origin");

//if (servletPath.contains("*.jsp") || servletPath.contains("/login") || servletPath.contains("/login.jsp") || servletPath.contains("/controller"))

{

res.addHeader("Access-Control-Allow-Origin", origin); //这里是设定的允许的域

res.addHeader("Access-Control-Allow-Headers", "X-CSRF-TOKEN");//这里主要是CSRF验证需要

res.addHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH");

res.addHeader("Access-Control-Allow-Credentials", "true");

}

String method = req.getMethod();

if (method.equals("OPTIONS"))

{

//默认OPTIONS的反应是返回302,Ajax对于302反应大家可以自己跟踪。

res.setStatus(200);

return;

}

}

js前端:不多解释,直接上代码。

(function($) {

    "use strict";

    var Business = Business || {};

    var RC = Business.RC = function () { };

    RC.prototype.login = function() {

        var d = $.Deferred();

var data = {

username:"sam",

password:"xxx"

};

var csrf_name = "";

var csrf_value = "";

var host = "http://192.168.1.102:8080";

function form()

{

$.ajax({

type: "GET",

crossDomain: true,

url: host + "/ShoppingMallWeb/login.jsp",

dataType: "text",

xhrFields: {

withCredentials: true // 为true时,Access-Control-Allow-Origin不能是*

},

complete: function (xhr, s) {

if (xhr.status == 200)

{

var result = xhr.responseText;

var ps = "";

var m = result.match(ps);

data[m[1]] = m[2];

csrf_name = m[1];

csrf_value = m[2];

d.resolve(result);

}

else

{

d.reject(xhr.responseText);

}

}

});

return d.promise();

}

function login() {

var d = $.Deferred();

$.ajax({

type: "POST",

crossDomain: true,

url: host + "/ShoppingMallWeb/controller/smw/login",

//url:host + "/ShoppingMallWeb/login",

beforeSend: function (request) {

request.setRequestHeader("X-CSRF-TOKEN", csrf_value);

request.setRequestHeader("Accept", "text/plain, **; q=0.01");

request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

},

dataType: "text",

xhrFields: {

withCredentials: true

},

data: data,

complete: function (xhr, s) {

if (xhr.status == 200) {

d.resolve(xhr.responseText);

}

else {

d.reject(xhr.responseText);

}

}

});

return d.promise();

}

function get() {

var d = $.Deferred();

$.ajax({

type: "GET",

crossDomain: true,

url: host + "/ShoppingMallWeb/controller/smw/get/sam",

dataType: "text",

xhrFields: {

withCredentials: true

},

complete: function (xhr, s) {

if (xhr.status == 200) {

alert(xhr.responseText);

d.resolve(xhr.responseText);

}

else {

d.reject(xhr.responseText);

}

}

});

return d.promise();

}

function post() {

var d = $.Deferred();

$.ajax({

type: "POST",

crossDomain: true,

url: host + "/ShoppingMallWeb/controller/smw/post/sam",

dataType: "text",

xhrFields: {

withCredentials: true

},

complete: function (xhr, s) {

if (xhr.status == 200) {

alert(xhr.responseText);

d.resolve(xhr.responseText);

}

else {

d.reject(xhr.responseText);

}

}

});

return d.promise();

}

form().then(login).then(get).then(post).then(logout);

      

    };

    $.rc = new RC();

})(jQuery);

上面代码,如果是从***.**发起的话,都通过了,包括IE(edge)、Firefox、Chrome,如果是从file://***发起的话,IE(edge)是不行的,Chrome和firefox是可以的,采用cordova技术的Android上的webview也不行。


内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/11246.html