ajax跨域
出于安全方面的考虑,Web浏览器中JavaScript无法访问其他服务器上的资源,这个限制仅在Web浏览器中有效。而跨域就是通过某些手段来绕过这个限制,实现不同服务器之间通信的效果。ajax跨域可以通过jsonp、cros或者服务端代理实现。 jsonpjsonp利用<script>标签不受限制访问其他服务器资源的特点,通过<script>的src发送跨域访问的url以及参数。jsonp需要对服务端返回的数据格式做修改,服务端返回的数据应该是一个可执行的JavaScript代码。 {"sex": "男","name": "小明","age": 20}
那么jsonp格式应该如下 callback({"sex": "男","age": 20});
其中callback是回调函数,一般由jsonp客户端提供。jQuery提供了jsonp请求,下面用jsonp获取京东的订单列表数据。 $.ajax({
url: 'http://order.jd.com/lazy/getOrderListCountJson.action',// jsonp路径
data: {},// 参数
//jsonp: 'callback',// 服务端接收回调函数的参数,默认是callback
//jsonpCallback: '',// 回调函数名称,如果不指定jQuery自动生成
dataType: 'jsonp' // 请求类型
}).done(function(json){
// 请求成功处理
console.dir(json);
}).fail(function(){
// 请求失败处理
});
如图所示,jsonp请求属于script请求。 jsonp结果如下 corsCORS(Cross-Origin Resource Sharing)定义一种跨域访问的机制,可以让AJAX实现跨域访问。实现此功能非常简单,只需服务器添加响应标头Access-Control-Allow-Origin。目前大部分的PC浏览器和几乎所有的移动浏览器都支持CROS。
服务端代码 import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.alibaba.fastjson.JSON;
@Controller
@RequestMapping("/test")
public class TestController {
/** * 返回json * * @param response */
@RequestMapping("/json.do")
public void json(HttpServletResponse response) {
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
// 添加响应头,支持跨域ajax请求
response.setHeader("Access-Control-Allow-Origin","*");
// 构造json
Map<String,Object> json = new HashMap<String,Object>();
json.put("date",new Date());
json.put("name","小明");
json.put("age",18);
try {
// 这里用FastJSON生成JSON字符串
response.getWriter().write(JSON.toJSONString(json));
} catch (IOException e) {
e.printStackTrace();
}
}
}
页面代码 $.ajax({
url: 'http://localhost:8280/logweb/test/json.do',dataType: 'json',success: function(json){
console.dir(json);
},error: function(){
}
});
如图所示,从CSDN页面发起ajax跨域请求。 如果服务端没有设置响应头Access-Control-Allow-Origin,浏览器会有如下错误提示。 服务端代理服务端不受跨域请求的限制,可以在服务端代理ajax请求。 import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
/** * ajax请求代理 * 用Apache HttpClient模拟发送请求 * 所有请求都以POST方式提交 */
@WebServlet("/ajax/proxy/servlet")
public class AjaxProxyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
// ajax请求的实际url名称
private final String destUrlParamName = "destUrl";
// 编码
private final String encoding = "utf-8";
protected void service(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
// 获取请求参数
List<NameValuePair> params = getParameters(request);
// ajax请求的实际url
String destUrl = request.getParameter(destUrlParamName);
HttpPost httppost = new HttpPost(destUrl);
CloseableHttpClient httpclient = HttpClients.createDefault();
UrlEncodedFormEntity formEntity;
try{
// 设置请求参数
formEntity = new UrlEncodedFormEntity(params,encoding);
httppost.setEntity(formEntity);
CloseableHttpResponse httppostResponse = httpclient.execute(httppost);
try{
HttpEntity httpEntity = httppostResponse.getEntity();
InputStream httpis = httpEntity.getContent();
OutputStream os = response.getOutputStream();
int len = 0;
byte[] buffer = new byte[1024];
while((len = httpis.read(buffer)) != -1){
os.write(buffer,0,len);
}
os.flush();
}finally{
httppostResponse.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
/** * 获取ajax请求参数 * @param request * @return 返回参数对数组 */
private List<NameValuePair> getParameters(HttpServletRequest request){
Enumeration<String> paramNames = request.getParameterNames();
List<NameValuePair> params = new ArrayList<NameValuePair>();
while(paramNames.hasMoreElements()){
String name = paramNames.nextElement();
// 判断,如果参数是ajax请求的目标路径,则忽略
if(!destUrlParamName.equals(name)){
params.add(new BasicNameValuePair(name,request.getParameter(name)));
}
}
return params;
}
}
ajax跨域请求代码 /** * ajax代理请求 * @param options ajax配置参数,请参考$.ajax()的配置 */
function ajaxProxy(options){
// ajax代理的url
var proxyUrl = 'http://localhost:8280/logweb/ajax/proxy/servlet',destUrl = options.url;
// 把代理url和实际url替换
options.url = proxyUrl;
if(!options.data){
options.data = {};
}
// 把实际url放到参数destUrl中,传递给服务端发送代理请求
options.data.destUrl = destUrl;
options.type = 'post';
return $.ajax(options);
}
下面用ajax代理请求博客园的分页数据 ajaxProxy({
url: 'http://www.cnblogs.com/mvc/AggSite/PostList.aspx',// 博客园分页url
dataType: 'html',// 数据格式是html
data: {
CategoryId: 808,CategoryType: "SiteHome",ItemListActionName: "PostList",PageIndex: 2,ParentCategoryId: 0
},success: function(html){
console.dir(html);
//把html直接输出到页面
$('body').html(html);
},error: function(){
console.dir(arguments);
}
});
请求参数如图所示 执行结果如图所示 总结
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |