angularjs跨域请求,html5封装进android与ios
前言
我使用的框架是springboot+angularjs ,内容主要包括: 下面主要针对以上几点来分别说说 为什么需要跨域
我简单的做了个比较. Web端打开新页面过程 App端打开新页面过程 过程比较:
由此可见,使用android或ios嵌套webview来达到一般原生的切换效果和访问服务器的速度,是很难的! 此时我们想到三个方案:
JS跨域请求s跨域请求需要在js和服务器端都有申明跨域,具体如下:
$.ajax({
type: 'POST',url: "/user",data: {
'phone': 'xxxxxxxx','password':'xxxxxxx'
},withCredentials: true,// 跨域
dataType: 'json'
}).success(function(){
});
$http.get(url,{
withCredentials : true //跨域
});
@Component
public class CorsFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,HttpServletResponse response,FilterChain filterChain) throws ServletException,IOException {
response.setHeader("Access-Control-Allow-Origin",request.getHeader("origin")); //允许跨域
response.setHeader("Access-Control-Allow-Credentials","true");
if ("OPTIONS".equals(request.getMethod())) {
response.setHeader("Access-Control-Allow-Methods","POST,GET,PUT,OPTIONS,DELETE");
response.setHeader("Access-Control-Max-Age","3600");
response.setHeader("Access-Control-Allow-Headers","Origin,X-Requested-With,Content-Type,Accept,Authorization");
}
filterChain.doFilter(request,response);
}
}
response.setHeader("Access-Control-Allow-Origin",request.getHeader("origin"));
这行代码是有点意思的,我这里没有将值直接设为“*”号,将值设为星号无法跨域发送cookies,需要发送cookies的可以设置成 request.getHeader("origin");
这样跨域发送请求就没有问题了。 使用localStorage替代本地Cookies
比如,登录成功后session在后台保存了用户会话信息,再次发送请求获取数据时,再次读取session验证用户身份时,始终无法取到登录时存储的会话信息,因为没有获取到cookies,而服务器与浏览器之间的会话sessionID是保存在cookies中的,为什么没有获取到cookies,是因为服务器端允许跨域是这样设置的: response.setHeader("Access-Control-Allow-Origin","*"); //允许跨域
origin设置成“*”,是不支持文件形式的访问所发送cookies的,需要怎么改呢?改成与本地文件一样的路径形式就成,比如,在我的机器上如果html路径是 file:///D:test.html,我在java端允许跨域就必须设置成 response.setHeader("Access-Control-Allow-Origin","file://"); //允许跨域
才能获取到cookies,考虑到html打包进ios或android app中的路径可能不同,则将路径设为: response.setHeader("Access-Control-Allow-Origin",request.getHeader("origin"));
这点可让我找了很久,“*”居然不行,我到现在也没想通。
登录的问题解决了,发送cookies也没有问题了,但是本地文件的cookies保存又出了问题,无法保存!也许有办法只是我没找到。 考虑到不同浏览器之间的差别和ios对cookies的可能支持不太好的问题,决定打算使用用localStorage在本地文件保存一些信息,因为localStorage是html5自带的,不存在不同浏览器之间的差别。 首先申明一个全局的storage,因为本身用他的目的就是替代cookies保存用户状态,当然是全局的啦 var storage = window.localStorage;
然后保存值 storage.setItem('userid','深蓝浅蓝的天')
取值 storage.getItem('userid');
退出清空storage storage.clear();
so easy,我很快就搜索全部代码将cookies的使用全部替换掉了(注意搜索路径哦),但是问题到了这里还是没有结束,在电脑上测试完了本地文件的访问都没有了问题,但是用android或ios打包html文件又出现问题了。
使用token替代跨域发送Cookiescookies既然有那么多的问题,而且可能在某些地方支持不太好,之后若是需要对app进行功能扩展,第三方授权之类的,也还是要走token,所以索性直接换掉cookies,当然,我在js中是有区分web/ios/android的,所以手机浏览器端仍然延续使用cookies,ios和android打包文件形式则用token。 虽然在服务器代码中session几乎无处不在,但要替换成token也不会特别麻烦,将原先保存在session中的数据,使用token作为一个键保存在redis中,然后在用户请求服务器时,拦截请求并取出token,再从redis中取出数据手动赋值到session中就可以了,只是我把原先服务器接收请求并取出cookies中sessionID,从而取出对应session的动作替换了下而已。 简单图示就是: 第一次请求服务器 大致过程如上图,用markdown不会画图,下次画个好点的~~
过程几乎是一样的,只是我在拦截中做了一步处理,以便我不需要大幅度改变原有代码,如下: @Override
public boolean preHandle(HttpServletRequest request,Object handler) throws Exception {
HttpSession session = request.getSession();
if (session.getAttribute("userId") == null) {
String token = request.getHeader("Authorization");
if (token != null && !token.equals("null")) {
String jsonToken = (String) redisTemplate.opsForValue().get(token);
UserToken userToken = JSON.parSEObject(jsonToken,UserToken.class);
if (userToken != null) {
session.setAttribute("userId",userToken.getUserId());
}
}
}
return true;
}
过程大致如此。 第一次写这么长的博文,欢迎指正。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |