前言
之前本人照葫芦画瓢做了个大概的云笔记,后来巧合之下租了个阿里云的服务器,于是就开始了部署项目的折腾之路
服务器环境准备
cloud_note是一个基于javaweb的项目,所以需要配置java环境,还有需要Tomcat启动服务,jdk我选择的是1.7.79,Tomcat7.0.23,然后就是安装,配置路径,这里就不多说了。
项目导出与部署
我使用的是eclipse,右击项目,export,导出war file
destination 选择你要导出的路径
然后将war文件上传到服务器上,放到webapps目录下,Tomcat启动运行之后会自动生成一个与你war文件名对应的文件夹,里面就包含了你项目的所有东西,如图
然后通过bin目录下的startup.bat启动Tomcat,可以在本地访问项目了。
值得一提的是,阿里云服务器需要在安全组开放对应的端口才可以访问,不然是无法访问的,例如启动Tomcat需要开放8080端口,还有数据库的3306端口也要开放
安全组–>配置规则–>添加安全组规则
至此项目服务器部署已经完毕
问题
部署完毕后我发现用服务器的公网ip加项目名无法访问项目,而且控制台也没有报错,后来在浏览器发现是无法加载资源,经老三提醒后发现是js跨域的问题,找到了方向之后成功解决了这个问题。第一次部署,没有留意到跨域的问题,莫名了很久,终于解决了。
js跨域
跨域访问,或者说 JavaScript 的跨域访问问题,是浏览器出于安全考虑而设置的一个限制,即同源策略。举例说明,当 A,B 两个网站属于不同的域时,如果来自于 A 网站的页面中的 JavaScript 代码希望访问 B 网站的时候,浏览器会拒绝该访问。
解决跨域方式有很多种,其中有jsonp,但是只能处理get请求。
所以我采用了CORS。
CORS
CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
简介
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
两种请求方式
浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request),浏览器对于两种请求的处理方式不一样。
满足以下两大条件就是简单请求
(1) 请求方法是以下三种方法之一:
HEAD
GET
POST
2)HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
java后台解决方法有两个:
第一种
1.自己建一个corsfilter类
package io.codegitz.cloud_note.filter;
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;
import org.springframework.stereotype.Component;
@Component
public class CorsFilter implements Filter{
//@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
//@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse)servletResponse;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Authorization");
response.setHeader("Access-Control-Allow-Credentials", "true");
filterChain.doFilter(servletRequest, servletResponse);
}
//@Override
public void destroy() {
}
}
预检请求会附带一些关于接下来的请求的信息给服务器,主要有以下几种:
Origin:请求的源域信息
Access-Control-Request-Method:接下来的请求类型,如POST、GET等
Access-Control-Request-Headers:接下来的请求中包含的用户显式设置的Header列表
服务器端收到请求之后,会根据附带的信息来判断是否允许该跨域请求,信息返回同样是通过Header完成的:
Access-Control-Allow-Origin:允许跨域的Origin列表
Access-Control-Allow-Methods:允许跨域的方法列表
Access-Control-Allow-Headers:允许跨域的Header列表
Access-Control-Expose-Headers:允许暴露给JavaScript代码的Header列表
Access-Control-Max-Age:最大的浏览器缓存时间,单位s
以上行为都是浏览器自动完成的,用户无需关注这些细节。如果服务器配置正确,那么和正常非跨域请求是一样的。
2.在web.xml文件中配置
<filter>
<filter-name>cors</filter-name>
<filter-class>io.codegitz.cloud_note.filter.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cors</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
第二种
这种方式似乎要spring4.2以上才支持,利用提供的jar包,下载 cors-filter-1.7.jar, java-property-utils-1.9.jar 这两个库文件放到lib目录下。(放到对应项目的webcontent/WEB-INF/lib/下),如果是maven项目,可以简单添加如下依赖到pom.xml中即可
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>cors-filter</artifactId>
<version>[ version ]</version>
</dependency>
接着添加CORS配置到web.xml文件中
<!-- 跨域配置,此filter应该放在所有filter之前-->
<filter>
<!-- The CORS filter with parameters -->
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
<!-- Note: All parameters are options, if omitted the CORS
Filter will fall back to the respective default values.
-->
<init-param>
<param-name>cors.allowGenericHttpRequests</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.allowOrigin</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowSubdomains</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>cors.supportedMethods</param-name>
<param-value>GET, HEAD, POST, OPTIONS</param-value>
</init-param>
<init-param>
<param-name>cors.supportedHeaders</param-name>
<param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified</param-value>
</init-param>
<init-param>
<param-name>cors.exposedHeaders</param-name>
<!--这里可以添加一些自己的暴露Headers -->
<param-value>X-Test-1, X-Test-2</param-value>
</init-param>
<init-param>
<param-name>cors.supportsCredentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.maxAge</param-name>
<param-value>3600</param-value>
</init-param>
</filter>
<filter-mapping>
<!-- CORS Filter mapping -->
<filter-name>CORS</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
配置完成之后可以发送另起一个项目或者页面来测试配置是否成功
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" src="scripts/jquery.min.js"></script>
<script type="text/javascript" src="scripts/basevalue.js"></script>
<script type="text/javascript">
$(function(){
//按钮单击时执行
$("#testAjax").click(function(){
//取Ajax返回结果
$.ajax({
url:path+"/test/ajax.do",
data:{},
dataType:"json",
type:"post",
success:function(result){
$("#myDiv").empty;
$("#myDiv").html(result.msg);
//显示Ajax返回结果
alert(result.msg);
},
error:function(){
alert("错误");
}});
});
});
</script>
</head>
<body>
<div id="myDiv"><h2>返回跨域的文本</h2></div>
<button id="testAjax" type="button">点击获取Ajax跨域返回内容</button>
</body>
</html>
浏览器输入http://47.106.120.224/cloud_note/Filter.html
成功返回文本跨域请求成功
小结
本次遇到的问题不大,都是没留意的小问题,倒是项目本身还有许多不完整的地方,bug多多,有时间再修改,源码稍后传到GitHub上,欢迎star。