一:案例实现

从网上下载了一个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 stub  
        HttpServletResponse 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 {  
    @Autowired  
    private UserOperate userOperate;  
      
    @RequestMapping(value="/getUser.do",method=RequestMethod.POST)  
    @ResponseBody  
    public 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方式

前端代码:

functiongetAdustryController($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",PUT");
response.setHeader("Access-Control-Allow-Headers",content-type");

在服务端设置:

response.setHeader("Access-Control-Allow-Origin",content-type");

AngularJS跨域问题的更多相关文章

  1. 关于h5中的fetch方法解读(小结)

    这篇文章主要介绍了关于h5中的fetch方法解读(小结),fetch身为H5中的一个新对象,他的诞生,是为了取代ajax的存在而出现,有兴趣的可以了解一下

  2. ios – 使用NSURLSession获取JSON数据

    我试图从谷歌距离api使用NSURLSession获取数据,但如下所示,当我打印响应和数据时,我得到的结果为NULL.可能是什么问题?

  3. ios – 错误域= com.alamofire.error.serialization.response代码= -1011“请求失败:禁止

    任何人都可以帮我解决以下错误–>在AFNetworking2.5中使用“删除”方法时出错解决方法我发现,如果我的手机时钟不同步……它不允许我更新…也许检查你的手机设置到正确的时间“自动区”,看看是否有效…

  4. iOS网页/原生应用Facebook登录弹出 – 失败?

    如果我重新启动app/web-app,用户将自动登录,并重定向到成功页面.我认为是导致问题的原因当您在Firefox/Chrome/Safari浏览器中运行网页时,Facebook登录对话框会弹出一个弹出窗口或另一个选项卡.我相信这是这个弹出页面的一个问题,以及当成功登录时Javascript如何与自身通信.window.close的东西没有返回的根页面…失败的解决方法由于应用程序挂在前面提到的URL上,我决定在shouldStartLoadWithRequest(…)中添加if语句以强制UIWebvie

  5. 通过AFNetworking 2.0上传iOS图像

    我一直在寻找新的AFNetworking2.0上传图像的例子.但是我正在撞墙,无法弄清楚代码有什么问题.所以这是我使用的代码TIA解决方法我最终使用了多部分请求

  6. ios – 在Objective-C中发送分块的HTTP 1.1请求

    我有以下问题:我正在创建一个非常大的SOAP请求(数据是一个编码为Base64字符串的视频),因此我不能将其作为原始SOAP请求发送,而是需要在HTTP1.1块中发送它.我似乎无法弄明白该怎么做.我在这里使用了代码:WhatarealternativestoNSURLConnectionforchunkedtransferencoding但它似乎没有做我认为应该做的事情–我可以看到请求作为单个请求

  7. ios – Watchkit新会话不起作用

    我的手表扩展中有两个视图控制器.每当我打电话时我只得到第一个视图控制器的响应,并在第二个viewcontroller中得到错误WCSession在app和watch扩展中启动.任何建议?

  8. 使用Firebase iOS Swift将特定设备的通知推送到特定设备

    我非常感谢PushNotifications的帮助.我的应用聊天,用户可以直接向对方发送短信.但是如果没有PushNotifications,它就没有多大意义.它全部设置在Firebase上.如何将推送通知从特定设备发送到特定设备?

  9. ios – 保存从查询中获取的用户的属性(即不在currentUser上)

    我有兴趣根据currentUser执行的操作将属性保存到数据库中的用户.基于以下代码,我收到错误消息“除非已通过logIn或signUp验证用户,否则无法保存用户”我想知道是否有一个解决方法,我可以将属性保存到foundUser,而无需登录该用户.谢谢你的帮助!解决方法如果要更新当前不是登录用户的用户,则需要使用主密钥调用Parse.您可以从CloudCode执行此操作;并从您的iOS项目中调用它;

  10. 在iOS中使用NSJSONSerialization进行JSON解析

    解决方法首先在您的JSON响应字典中,在“RESPONSE”键下,您有一个数组而不是字典,该数组包含字典对象.所以要提取用户名和电子邮件ID,如下所示

随机推荐

  1. Angular2 innerHtml删除样式

    我正在使用innerHtml并在我的cms中设置html,响应似乎没问题,如果我这样打印:{{poi.content}}它给了我正确的内容:``但是当我使用[innerHtml]=“poi.content”时,它会给我这个html:当我使用[innerHtml]时,有谁知道为什么它会剥离我的样式Angular2清理动态添加的HTML,样式,……

  2. 为Angular根组件/模块指定@Input()参数

    我有3个根组件,由根AppModule引导.你如何为其中一个组件指定@input()参数?也不由AppModalComponent获取:它是未定义的.据我所知,你不能将@input()传递给bootstraped组件.但您可以使用其他方法来做到这一点–将值作为属性传递.index.html:app.component.ts:

  3. angular-ui-bootstrap – 如何为angular ui-bootstrap tabs指令指定href参数

    我正在使用角度ui-bootstrap库,但我不知道如何为每个选项卡指定自定义href.在角度ui-bootstrap文档中,指定了一个可选参数select(),但我不知道如何使用它来自定义每个选项卡的链接另一种重新定义问题的方法是如何使用带有角度ui-bootstrap选项卡的路由我希望现在还不算太晚,但我今天遇到了同样的问题.你可以通过以下方式实现:1)在控制器中定义选项卡href:2)声明一个函数来改变控制器中的散列:3)使用以下标记:我不确定这是否是最好的方法,我很乐意听取别人的意见.

  4. 离子框架 – 标签内部的ng-click不起作用

    >为什么标签标签内的按钮不起作用?>但是标签外的按钮(登陆)工作正常,为什么?>请帮我解决这个问题.我需要在点击时做出回复按钮workingdemo解决方案就是不要为物品使用标签.而只是使用divHTML

  5. Angular 2:将值传递给路由数据解析

    我正在尝试编写一个DataResolver服务,允许Angular2路由器在初始化组件之前预加载数据.解析器需要调用不同的API端点来获取适合于正在加载的路由的数据.我正在构建一个通用解析器,而不是为我的许多组件中的每个组件设置一个解析器.因此,我想在路由定义中传递指向正确端点的自定义输入.例如,考虑以下路线:app.routes.ts在第一个实例中,解析器需要调用/path/to/resourc

  6. angularjs – 解释ngModel管道,解析器,格式化程序,viewChangeListeners和$watchers的顺序

    换句话说:如果在模型更新之前触发了“ng-change”,我可以理解,但是我很难理解在更新模型之后以及在完成填充更改之前触发函数绑定属性.如果您读到这里:祝贺并感谢您的耐心等待!

  7. 角度5模板形式检测形式有效性状态的变化

    为了拥有一个可以监听其包含的表单的有效性状态的变化的组件并执行某些组件的方法,是reactiveforms的方法吗?

  8. Angular 2 CSV文件下载

    我在springboot应用程序中有我的后端,从那里我返回一个.csv文件WheniamhittingtheURLinbrowsercsvfileisgettingdownloaded.现在我试图从我的角度2应用程序中点击此URL,代码是这样的:零件:服务:我正在下载文件,但它像ActuallyitshouldbeBook.csv请指导我缺少的东西.有一种解决方法,但您需要创建一个页面上的元

  9. angularjs – Angular UI-Grid:过滤后如何获取总项数

    提前致谢:)你应该避免使用jQuery并与API进行交互.首先需要在网格创建事件中保存对API的引用.您应该已经知道总行数.您可以使用以下命令获取可见/已过滤行数:要么您可以使用以下命令获取所选行的数量:

  10. angularjs – 迁移gulp进程以包含typescript

    或者我应该使用tsc作为我的主要构建工具,让它解决依赖关系,创建映射文件并制作捆绑包?

返回
顶部