玩转spring boot——ajax跨域

摘要:
前言java语言在多数时,会作为一个后端语言,为前端的php,node.js等提供API接口。前端通过ajax请求去调用java的API服务。今天以node.js为例,介绍两种跨域方式:CrossOrigin和反向代理。

前言


java语言在多数时,会作为一个后端语言,为前端的php,node.js等提供API接口。前端通过ajax请求去调用java的API服务。今天以node.js为例,介绍两种跨域方式:CrossOrigin和反向代理。

一、准备工作


pom.xml:

玩转spring boot——ajax跨域第1张
复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>spring-boot-15</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>spring-boot-15</name>
    <description>Demo project for Spring Boot</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
复制代码

App.java

复制代码
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication
@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}
复制代码

User.java

复制代码
package com.example;
public class User {
    public int id;
    public String name;
    public int age;
}
复制代码

MainController.java:

复制代码
package com.example;
import java.util.ArrayList;
import java.util.List;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * 控制器 博客出处:http://www.cnblogs.com/GoodHelper/
 *
 */
@RestController
public class MainController {
    @GetMapping("findAllUser")
    public List<User> findAllUser() {
        List<User> list = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            User user = new User();
            list.add(user);
            user.id = i;
            user.name = "name_" + i;
            user.age = 20 + i;
        }
        return list;
    }
}
复制代码

项目结构如下图所示:

玩转spring boot——ajax跨域第10张

访问http://localhost:8080/findAllUser

玩转spring boot——ajax跨域第11张

使用HBuilder创建node.js express项目:

玩转spring boot——ajax跨域第12张

选择ejs模板引擎:

玩转spring boot——ajax跨域第13张

index.ejs文件代码如下:

复制代码
<!DOCTYPE html>
<html>
    <head>
        <title>
            <%= title %>
        </title>
        <link rel='stylesheet' href='http://t.zoukankan.com/stylesheets/style.css' />
        <script src="http://cdn.bootcss.com/angular.js/1.5.6/angular.min.js"></script>
        <script type="text/javascript">
            var app = angular.module('app', []);
            app.controller('MainController', function($rootScope, $scope, $http) {
                $http({
                    method: 'GET',
                    url: 'http://localhost:8080/findAllUser'
                }).then(function successCallback(r) {
                    $scope.rows = r.data;
                });
            });
        </script>
    </head>
    <body ng-app="app" ng-controller="MainController">
        <h1><%= title %></h1>
        <p>Welcome to
            <%= title %>
        </p>
        <br />
        <table>
            <tr ng-repeat="row in rows">
                <td>{{row.id}}</td>
                <td>{{row.name}}</td>
                <td>{{row.age}}</td>
            </tr>
        </table>
    </body>
</html>
复制代码

通过angular.js的http方法调用api请求

右键运行项目:

玩转spring boot——ajax跨域第16张

运行效果:

玩转spring boot——ajax跨域第17张

发现调用ajax请求时跨域失败。

二、spring boot后台设置允许跨域


这时,修改MainController类,在方法前加@CrossOrigin注解:

复制代码
/**
 * 控制器 博客出处:http://www.cnblogs.com/GoodHelper/
 *
 */
@RestController
public class MainController {
    @CrossOrigin(origins = "http://localhost:3000")
    @GetMapping("findAllUser")
    public List<User> findAllUser() {
        List<User> list = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            User user = new User();
            list.add(user);
            user.id = i;
            user.name = "name_" + i;
            user.age = 20 + i;
        }
        return list;
    }
}
复制代码

这是声明findAllUser方法允许跨域,

也可以修改App.java,来实现全局跨域:

复制代码
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedOrigins("http://localhost:3000");
            }
        };
    }
}
复制代码

registry.addMapping("/**"):为根目录的全部请求,也可以设置为"/user/**",这意味着是user目录下的所有请求。

在访问http://localhost:3000,效果如下:

玩转spring boot——ajax跨域第22张

三、通过node.js的方向代理实现跨域


node.js提供了一些反向代理的中间件,能轻而易举的实现跨域,而不需要spring boot做任何设置。

安装express-http-proxy中间件

npm install --save-dev express-http-proxy

玩转spring boot——ajax跨域第23张

修改app.js文件,使其支持反向代理:

var proxy = require('express-http-proxy');
var apiProxy = proxy('http://localhost:8080', {});
app.use('/api', apiProxy);

以“/api”开头的请求转发为spring boot的API服务。

完整代码如下:

玩转spring boot——ajax跨域第1张
复制代码
/**
 * Module dependencies.
 */
var express = require('express')
  , routes = require('./routes')
  , user = require('./routes/user')
  , http = require('http')
  , path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}
var proxy = require('express-http-proxy');
var apiProxy = proxy('http://localhost:8080', {});
app.use('/api', apiProxy);
app.get('/', routes.index);
app.get('/users', user.list);
http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});
复制代码

修改index.ejs文件:

复制代码
            var app = angular.module('app', []);
            app.controller('MainController', function($rootScope, $scope, $http) {
                $http({
                    method: 'GET',
                    url: '/api/findAllUser'
                }).then(function successCallback(r) {
                    $scope.rows = r.data;
                });
            });
   
复制代码

完整的index.ejs文件如下:

玩转spring boot——ajax跨域第1张
复制代码
<!DOCTYPE html>
<html>
    <head>
        <title>
            <%= title %>
        </title>
        <link rel='stylesheet' href='http://t.zoukankan.com/stylesheets/style.css' />
        <script src="http://cdn.bootcss.com/angular.js/1.5.6/angular.min.js"></script>
        <script type="text/javascript">
            var app = angular.module('app', []);
            app.controller('MainController', function($rootScope, $scope, $http) {
                $http({
                    method: 'GET',
                    url: '/api/findAllUser'
                }).then(function successCallback(r) {
                    $scope.rows = r.data;
                });
            });
        </script>
    </head>
    <body ng-app="app" ng-controller="MainController">
        <h1><%= title %></h1>
        <p>Welcome to
            <%= title %>
        </p>
        <br />
        <table>
            <tr ng-repeat="row in rows">
                <td>{{row.id}}</td>
                <td>{{row.name}}</td>
                <td>{{row.age}}</td>
            </tr>
        </table>
    </body>
</html>
复制代码

运行效果如下:

玩转spring boot——ajax跨域第32张

总结


第二种通过反向代理的方式是最佳方案。在正式项目中,可以使用node.js控制web前端渲染与spring boot后端提供API服务的组合。这样,可以控制用户在node.js端登录后才能调用spring boot的API服务。在大型web项目中也可以使用node.js的反向代理,把很多子站点关联起来,这样便发挥出了网站灵活的扩展性。

参考:https://spring.io/guides/gs/rest-service-cors/

代码地址:https://github.com/carter659/spring-boot-15.git

返回玩转spring boot系列目录

作者:刘冬.NET 博客地址:http://www.cnblogs.com/GoodHelper/ 欢迎转载,但须保留版权

http://www.cnblogs.com/GoodHelper/p/6824562.html

免责声明:文章转载自《玩转spring boot——ajax跨域》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇利用PHP判断iPhone、iPad、Android、PC设备减少Qt编译时间暨简单Qt裁剪下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

宜信数据采集平台DBus-allinone部署实战案例

          宜信数据采集平台DBus-All In One部署实战案例                                      作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任。   官方文档可参考:https://github.com/BriData/DBus/blob/master/docs/quick-star...

国产操作系统——银河麒麟V10 SP1使用小结

前几天看新闻国产操作系统银河麒麟有了新的更新于是上手搞了一个。     ========================================================= 该系统自带驱动,其中包括NVIDIA的显卡驱动,十分神奇,不过这也造成了一个问题就是你自己不好再安装驱动了。   自己手动安装银河麒麟的NVIDIA-driver-...

视频播放器测试点

一、常规视频播放器本身测试点视频资源大小测试-能正常渲染视频 正常长度视频10分钟左右、短视频、超长视频5g 视频格式测试-能正常渲染视频 目前支持的视频格式:支持mp4、mov、flv、avi、asf、wmv、webm、mpg 视频录制状态测试-能正常渲染视频,大小屏/横竖屏播放正常 录制时是横屏、竖屏 播放、暂停视频 音量(静音) 速度校验(倍...

CCXT

CCXT 一,简介 JavaScript / Python / PHP加密货币交易API,支持超过120个比特币/山寨币交换 提供对市场数据的快速访问,以进行存储,分析,可视化,指标开发,算法交易,策略回测,自动程序编程和相关软件工程。 旨在供编码人员,开发人员,技术熟练的交易员,数据科学家和财务分析人员用来构建交易算法。 二,特点 支持许多加密货币...

APP测试点总结(功能,交互,死机崩溃状态分析,容易出错的检查点)

APP测试点总结(功能,交互,死机崩溃状态分析,容易出错的检查点) 版权声明:本文为博主原创文章,未经博主允许不得转载。 最近涉足APP端测试,常见检查点总结如下:   一.业务方面: 1.  注册(无效数据剔除),登录(语音和短信验证码),第三方登录(微信,微博,qq),忘记密码处理,注册   (登录后身份判断校验);账号互踢(同一时间一个账号只能在一台...

pywinauto客户端自动化---应用窗口的操作方法

前面知道了如果打开应用软件和指定打开启动的应用软件,这一篇介绍如何如何对应用窗口进行操作 窗口是什么 窗口是什么?窗口就是应用软件上面的工具栏,操作栏,弹出菜单,对话框等,这些基本上为windows软件应用比较多的地方。 如何获取窗口信息 方法一: 直接通过viewWizard工具进行获取窗口信息(这里通过进行点去想要获取的位置进行获取) 方法二: 通过...