为什么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 跨域相关推荐

  1. 如何解决ajax跨域java,ajax跨域问题,从java角度解决

    前言 今天给小伙伴开放一个接口方便调试数据,但是老是出现CROS策略阻塞,查询资料后知道了是ajax跨域引起的,以此记录此次解决问题的过程. 什么是ajax跨域 ajax跨域的原理 ajax出现请求跨 ...

  2. 【转】JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  3. JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  4. apache ajax 跨域访问,AJAX跨域访问(从Tomcat8到Apache/Nginx)

    1.在Tomcat的Root目录下放入如下的文件 apache-tomcat-8.0.12X64\webapps\ROOT clientaccesspolicy.xml文件 crossdomain.x ...

  5. 菜鸟教程 php跨域,PHP Ajax 跨域问题最佳解决方案

    本文通过设置Access-Control-Allow-Origin来实现跨域. 例如:客户端的域名是client.runoob.com,而请求的域名是server.runoob.com. 如果直接使用 ...

  6. ajxs跨域 php_PHP Ajax 跨域问题最佳解决方案

    本文通过设置Access-Control-Allow-Origin来实现跨域. 例如:客户端的域名是edu.jb51.net,而请求的域名是edu.jb51.net. 如果直接使用ajax访问,会有以 ...

  7. ajax跨域异常,ajax跨域问题

    省 市 县 $(document).ready(function () { $("show").click(function () { $.ajax({ dataType:'jso ...

  8. html 图片上传跨域,html5 ajax 跨域上传图片

    html: js: // 读取地址 function readURL(input, tmpimg) { if (input.files && input.files[0]) { var ...

  9. Ajax跨域:Jsonp原理解析

    推荐先看下这篇文章:JS跨域(ajax跨域.iframe跨域)解决方法及原理详解(jsonp) JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在JavaScript中,有一个很重 ...

最新文章

  1. eve战巡族伤害_新版本各族3级战巡资料【纯手打】
  2. 发现自己的idea已经被人发表了,该怎么办?研究生灵魂发问,引起热烈讨论
  3. 《Java和Android开发学习指南(第2版)》——第2章,第2.10节本章小结
  4. 鸿蒙之光一星辰是什么意思,如果说安卓的目标是太阳,那么鸿蒙的目标就是星辰大海...
  5. 抓包工具Charles使用技巧
  6. react apollo_Apollo GraphQL:如何使用React和Node Js构建全栈应用
  7. 去360总部参加网络信息安全会议经历
  8. 全球首款5g全网通智能路由器华为5G CPE Pro发布 售价2499元
  9. Aspose.Words转换为PDF的时候字体丢失的问题解决
  10. unix环境高级编程-文件和目录(1)
  11. 什么叫做:离线下载?-by:nixs
  12. ubuntu下如何对接斗鱼直播
  13. 第十二届蓝桥杯真题-左孩 子右兄弟(dfs)
  14. Sharepoint Solution Gallery Active Solution时激活按钮灰色不可用的解决方法
  15. C语言头文件里可以写些什么
  16. 国内两家3D打印企业入选微软加速器创业加速计划
  17. 忍者必须死显示无法连接服务器,忍者必须死为什么不能登录
  18. 亚马逊测评自养号环境系统的介绍和用法
  19. Mac os删除自带ABC输入法,只保留搜狗输入法
  20. 计算机信息技术五大变革,信息技术及其影响教学设计

热门文章

  1. HADOOP2单机版
  2. Hadoop运维记录系列(三)
  3. 各品牌笔记本BIOS设置硬盘为兼容模式(IDE)方法
  4. 黄淮学院计算机录取线,黄淮学院录取投档线
  5. 关于在hdfs上对数据创建外部表的原因
  6. deepfm代码参考
  7. git遇到的一些问题
  8. lnmp 60秒的服务器缓存时间
  9. 自适应高度Textarea
  10. Git 工具 - 子模块 外部引用