AngularJS跨域问题 ajax 跨域
为什么80%的码农都做不了架构师?>>>
先看代码:
$http({method: 'POST',//withCredentials: true, //这个用来将cookie传回服务器,但是post请求设置这个将导致errorheaders: {'Content-Type': 'application/x-www-form-urlencoded',//跨站必须,否则浏览器自动将method改为options },url: 'http://192.168.14.136:8888/api/v1.0/login/',data: data1,/*transformRequest: function(obj) {//这个用来把json变为p1=v1&p2=v2这种形式var str = [];for (var p in obj) {str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));}return str.join("&");}*/}).success(function(data) {alert(data);}).error(function(data) {alert(data);});//服务器端必须返回头如下才会success
response.setHeader("Access-Control-Allow-Origin", "*");//如果要传递cookie这里不能使用通配符,而是要用下面的方式
response.addHeader("Access-Control-Allow-Credentials", "true"); //接受cookie传递
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin")); //匹配客户端发来的Origin并返回去,这样ajax才能success。
response.setHeader("Access-Control-Allow-Methods","POST");
response.setHeader("Access-Control-Allow-Headers","x-requested-with,content-type");python:self.set_header("Content-Type","application/json")self.set_header("Access-Control-Allow-Origin",self.request.headers.get("Origin", "*"))self.set_header("Access-Control-Allow-Credentials","true")self.set_header("Access-Control-Allow-Methods","POST,GET,OPTIONS")self.set_header("Access-Control-Allow-Headers","x-requested-with,content-type")注意:返回json的格式必须严谨,否则会ajax err
一:案例实现
从网上下载了一个AngularJS项目,配置启动后发现数据发送不到自己的后台中去,总是提示跨域问题。
下面是AngularJS的部分代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html ng-app=""> <head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta http-equiv="Access-Control-Allow-Origin" content="*"><title>AngularJSTest</title> </head> <body ng-controller="MyController"> <p>User</p> <p>ID</p> <input id="id" name="id" ng-model="saveUser.id"> <br> <p>Name</p> <input id="id" name="name" ng-model="saveUser.name"> <br> <p>age</p> <input id="id" name="age" ng-model="saveUser.age"> <br> <ul><li ng-repeat="x in infos">{{ x.ID + x.name + x.age }}</li> </ul> <button ng-click="getUser()">提交</button> <script>function MyController($scope, $http){$scope.saveUser = {id:1,name:"John",age:"16"};$scope.getUser = function(){$http({method: "POST",url: "http://localhost:8080/Spring-MVC/AngularJS/getUser.do",data: $scope.saveUser}).success(function (data){$scope.infos = data;})};} </script> <script src="lib/angular/angular.js"></script> </body> </html>
注意:在$http中URL前部分为后台项目的路径。
后台需要自己写一个过滤器,并配置到web.xml中去
package com.jxq.util;import java.io.IOException;import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse;public class RequestFilter implements Filter {public void init(FilterConfig filterConfig) throws ServletException {// TODO Auto-generated method stub}public void doFilter(ServletRequest request, ServletResponse pResponse, FilterChain chain)throws IOException, ServletException {// TODO Auto-generated method stubHttpServletResponse response = (HttpServletResponse) pResponse;response.setHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Methods", "POST,GET,DELETE,PUT");response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");chain.doFilter(request, response);}public void destroy() {// TODO Auto-generated method stub}}
web.xml中的配置
<filter><filter-name>requestFilter</filter-name><filter-class>com.jxq.util.RequestFilter</filter-class></filter><filter-mapping><filter-name>requestFilter</filter-name><url-pattern>*.do</url-pattern></filter-mapping>
Controller的写法:
package com.jxq.controller.user;import java.util.ArrayList; import java.util.List;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody;import com.jxq.entity.user.AngularUser; import com.jxq.service.user.UserOperate;@Controller @RequestMapping(value="/AngularJS") public class UserController {@Autowiredprivate UserOperate userOperate;@RequestMapping(value="/getUser.do", method=RequestMethod.POST)@ResponseBodypublic List<AngularUser> save(@RequestBody AngularUser angularUser){System.out.println("ID:" + angularUser.getId());System.out.println("name:" + angularUser.getName());System.out.println("age:" + angularUser.getAge());List<AngularUser> lists = new ArrayList<AngularUser>();AngularUser user1 = new AngularUser();user1.setId("001");user1.setAge("25");user1.setName("zhangsan");lists.add(user1);AngularUser user2 = new AngularUser();user2.setId("002");user2.setAge("26");user2.setName("lisi");lists.add(user2);AngularUser user3 = new AngularUser();user3.setId("003");user3.setAge("27");user3.setName("wangwu");lists.add(user3);return lists;} }
必须要加上@responseBody,否则无法返回数据给前端,稍后的博客会详细介绍@requestBody和@responseBody
二:跨域问题详解
下面详细说一下AngularJS的$http请求跨域,此部分为网上查询得到。
跨域,前端开发会经常遇见,AngularJS实现跨域方式类似于Ajax,使用的是CORS机制。
1:CORS机制:
是一种允许当前域的资源被其他域的脚本请求访问的机制。整个请求都是浏览器自动完成,不需要用户参与,会自动添加一些附加的头信息,有时候会多发出一次附加的请求。
分为两种:简单请求和非简单请求。
区别在于只要满足两类条件,就是简单请求。
(1):请求方法是一下三种方法之一:HEAD、GET和POST
(2):请求的头信息不超过一下几种字段:
Accept、Accept-Language、Content-Language、Last-Event-ID和Content-Type
其中Content-Type的值:application/x-www-form-urlencoded、multipart/form-data和text/plain
凡是不满足上述两个条件的,都是非简单请求。浏览器对于这两种请求的处理方式是不一样的。
a:简单请求
对于简单请求,浏览器直接发出CORS请求,就是在头信息中会增加一个Origin字段.
Origin字段用来说明本次请求来自哪个源(协议+域名+端口),服务器根据这个值,决定是否同意这次请求。
如果是不在许可范围内,服务器会返回一根正常的HTTP回应,但是没有包括Access-Control-Allow-Origin字段,就知道是出错了,从而跑出错误,被XMLHttpRequest的onerror回调函数捕获。
注意:这种错误是无法通过状态码识别,因为HTTP回应可能是200。
如果Origin制定的域名在许可范围内,服务器返回的响应,就会多几个头信息字段。
红色框括起来的,是可CORS请求想看的字段,都是以Access-Control-开头
(1):Access-Control-Allow-Origin
该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任何域名的请求。
(2):Access-Control-Allow-Credentials
可选,是一个布尔值,表示是否允许发送Cookie,默认情况下,Cookie不包括在CORS请求之中,设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发送给服务器。这个值也只能设为true。如果不需要浏览器发送Cookie给服务器,删除即可。
(3):Access-Control-Expose-Headers
可选,CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。上面的例子指定,getResponseHeader('FooBar')可以返回FooBar字段的值。
b:非简单请求
是那种对服务器有特殊要求的请求,请求方法是PUT或DELETE,或者Content-Type类型为application/json
首先是预检测:在正式通讯之前,发送一次查询请求,询问是否在许可名单中以及可以使用那些HTTP动词和头信息。只有得到答复,才会正式发起请求,否则报错。
预检测通过之后,浏览器就会发送一个正常的请求。
c:与JSONP的比较
JSONP只支持GET请求,CORS支持所有的类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。
2:AngularJS的$http
AngularJS的$http请求方式:
$http.post(url, data, [config]).success(function(){ ... }); $http.get(url, [config]).success(function(){ ... });
(1):JSONP方式:
指定callback和回调函数名,函数名为JSON_CALLBACK时,会调用success回调函数,JSON_CALLBACK必须全为大写。
$http.jsonp("http://localhost/sitesettings/getBadgeInfo.pt?jsonp=JSON_CALLBACK&siteid=137bd406").success(function(data){ ... });
(2):get方式
前端代码:
function getAdustryController($scope,$http){$http.get('http://localhost/ajax/getAllIndustryCategoty.pt?languageColumn=name_eu').success(function(data){$scope.industries = data;}); }
(3)POST请求:
在服务端设置允许在其他域名下访问、响应类型、响应头
response.setHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Methods", "POST,GET,DELETE,PUT");response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");
在服务端设置:
response.setHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Methods", "POST,GET,DELETE,PUT");response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");
转载于:https://my.oschina.net/u/1777508/blog/1589159
AngularJS跨域问题 ajax 跨域相关推荐
- 如何解决ajax跨域java,ajax跨域问题,从java角度解决
前言 今天给小伙伴开放一个接口方便调试数据,但是老是出现CROS策略阻塞,查询资料后知道了是ajax跨域引起的,以此记录此次解决问题的过程. 什么是ajax跨域 ajax跨域的原理 ajax出现请求跨 ...
- 【转】JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)
这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...
- JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)
这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...
- apache ajax 跨域访问,AJAX跨域访问(从Tomcat8到Apache/Nginx)
1.在Tomcat的Root目录下放入如下的文件 apache-tomcat-8.0.12X64\webapps\ROOT clientaccesspolicy.xml文件 crossdomain.x ...
- 菜鸟教程 php跨域,PHP Ajax 跨域问题最佳解决方案
本文通过设置Access-Control-Allow-Origin来实现跨域. 例如:客户端的域名是client.runoob.com,而请求的域名是server.runoob.com. 如果直接使用 ...
- ajxs跨域 php_PHP Ajax 跨域问题最佳解决方案
本文通过设置Access-Control-Allow-Origin来实现跨域. 例如:客户端的域名是edu.jb51.net,而请求的域名是edu.jb51.net. 如果直接使用ajax访问,会有以 ...
- ajax跨域异常,ajax跨域问题
省 市 县 $(document).ready(function () { $("show").click(function () { $.ajax({ dataType:'jso ...
- html 图片上传跨域,html5 ajax 跨域上传图片
html: js: // 读取地址 function readURL(input, tmpimg) { if (input.files && input.files[0]) { var ...
- Ajax跨域:Jsonp原理解析
推荐先看下这篇文章:JS跨域(ajax跨域.iframe跨域)解决方法及原理详解(jsonp) JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在JavaScript中,有一个很重 ...
最新文章
- eve战巡族伤害_新版本各族3级战巡资料【纯手打】
- 发现自己的idea已经被人发表了,该怎么办?研究生灵魂发问,引起热烈讨论
- 《Java和Android开发学习指南(第2版)》——第2章,第2.10节本章小结
- 鸿蒙之光一星辰是什么意思,如果说安卓的目标是太阳,那么鸿蒙的目标就是星辰大海...
- 抓包工具Charles使用技巧
- react apollo_Apollo GraphQL:如何使用React和Node Js构建全栈应用
- 去360总部参加网络信息安全会议经历
- 全球首款5g全网通智能路由器华为5G CPE Pro发布 售价2499元
- Aspose.Words转换为PDF的时候字体丢失的问题解决
- unix环境高级编程-文件和目录(1)
- 什么叫做:离线下载?-by:nixs
- ubuntu下如何对接斗鱼直播
- 第十二届蓝桥杯真题-左孩 子右兄弟(dfs)
- Sharepoint Solution Gallery Active Solution时激活按钮灰色不可用的解决方法
- C语言头文件里可以写些什么
- 国内两家3D打印企业入选微软加速器创业加速计划
- 忍者必须死显示无法连接服务器,忍者必须死为什么不能登录
- 亚马逊测评自养号环境系统的介绍和用法
- Mac os删除自带ABC输入法,只保留搜狗输入法
- 计算机信息技术五大变革,信息技术及其影响教学设计