GVKun编程网logo

javaweb 中 ajax 跨域访问实例(javaweb跨域请求)

30

本篇文章给大家谈谈javaweb中ajax跨域访问实例,以及javaweb跨域请求的知识点,同时本文还将给你拓展AJAXjavascript的跨域访问执行、ajaxpost跨域访问、ajax跨域访问、

本篇文章给大家谈谈javaweb 中 ajax 跨域访问实例,以及javaweb跨域请求的知识点,同时本文还将给你拓展AJAX javascript的跨域访问执行、ajax post 跨域访问、ajax 跨域访问、Ajax 跨域访问 tomcat 下的 web service等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

javaweb 中 ajax 跨域访问实例(javaweb跨域请求)

javaweb 中 ajax 跨域访问实例(javaweb跨域请求)

AJAX 跨域解决方法 

跨域,简单地理解就是因为浏览器基于安全的同源策略限制不同域名和协议之间的互相访问。

而 AJAX 的跨域请求,其实浏览器并没有限制不同域的网络请求,只是浏览器会基于请求返回响应头做处理,如果发现是跨域请求且响应头 Access-Control-Allow-Origin 未对请求来源设置允许,则根据非同源禁止策略,浏览器不会将服务端返回的数据交给 AJAX,这样就会阻止不同域之间的数据交互。

介绍两张常用的低廉的解决方案:

1)服务端对访问的来源设置 Access-Control-Allow-Origin 响应头许可;

此方法不需要 javascript 做任何改动,只需要服务端层面做处理,相对来说简单易用。

response.setHeader("Access-Control-Allow-Origin""*");

感觉这个接口太开放了,不太安全。

如果想只设置自己指定的若干个域名或者端口可以调用接口。

response.addHeader("Access-Control-Allow-Origin","http://a.com,http://b.com");

2)JSONP

jsonp 的实现原理,其实就是通过动态加载 script 标签,预先定义好 callback 函数处理逻辑,服务端返回的数据其实是一个执行函数的代码,将有效数据作为 callback 函数的参数。

此方法需要前端和服务端同时做支持,实现成本也比较低廉。

$.ajax({
    url:"http://192.168.6.21:8080/jsonp/servlet/Ajax",
   data:"data=guoyansi",
   type:"get",

   dataType:"jsonp",

  jsonp:"callbackparam",// 传递给请求处理程序或页面的,用以获得 jsonp 回调函数名的接受 的参数名 (默认为 callback)

   jsonpCallback:"jsonpCallback",// 可选项,写上表示返回函数的函数名用 “jsonpCallback”,不写 默认为 jQuery 自动生成的随机函数,
   error:function (){alert ("服务器连接失败");},
   success:function(data){
   for(var key in data){
    alert(key+":"+data[key]);
   }
  }

 });

 import net.sf.json.JSONArray;
 import net.sf.json.JSONObject;

public class Ajax extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
    response.setContentType("text/plain");
    response.setCharacterEncoding("utf-8");
    String callbackparam=request.getParameter("callbackparam");
    System.out.println("callbackparam:"+callbackparam);
    String name=request.getParameter("data");
    System.out.println("param:"+name);
    Map<String, String> map=new HashMap<String, String>();
    map.put("1", "a");
    map.put("2", "b");
    map.put("3", "c");
    map.put("4", "d");
    JSONObject jsonObject=JSONObject.fromObject(map);
    String result=jsonObject.toString();
    PrintWriter writer=response.getWriter();

// 如果 ajax 请求写了 jsonpCallback:"jsonpCallback",
    writer.write("jsonpCallback("+result+")");

// 如果 ajax 请求没有写 jsonpCallback:"jsonpCallback",

    writer.write (callbackparam+"("+result+")");// 需要 callbackparam 参数接收随机函数名

}

}

跨域请求,服务端的 session 会话会被跨域请求覆盖改掉

tomcat 使用 cookie 中 jsessionid 来区分客户端 session 会话

跨域请求接口恰恰有时候响应回来会改变服务端的 jsessionid 值,导致服务器每次判断都是一个新的会话

如果 Response 一个 cookie 值,SET-COOKIE:JSESSIONID=XXXX

服务端,前端刷新一次也没,后端服务会话 id 都不是同一个 sessionid,所有后端所有的请求都是未登录,这就导致前端发送的请求,后端无法拿到当前个人用户信息

服务端部署采用 tomcat,所以修改办法是在 $TOMCAT_TOME/conf/catalina.properties 文件中加上一句,

org.apache.catalina.SESSION_COOKIE_NAME=MYSESSIONID

设置 sessionId 的 cookieName 别名,不和默认的 jsessionid 一直,

最终修改好后,再看服务器的 cookie 值,服务端使用 session 取的 cookie 值是刚刚设置的别名 cookie 值 MYSESSIONID, 所以不受跨域接口影响

AJAX javascript的跨域访问执行

AJAX javascript的跨域访问执行

javascript0.jpg
突然感觉就是这里的问题,研究一下,搞定后其实觉得挺容易的,只是自己知识还是有些欠缺,解决方法如下:

阻塞的AJAX请求

  我们先来证实一下请求的阻塞情况吧。我们使用如下的代码:

 连续发起三个请求 
复制代码 代码如下:

function simpleRequest() 

   var request = new XMLHttpRequest(); 
    request.open(”POST“, “Script.ashx“); 
    request.send(null); 
}
function threeRequests() 

    simpleRequest(); 
    simpleRequest(); 
    simpleRequest(); 


   当执行threeRequests时就会连续发出3个相同域名的请求,还是通过统计图表来查看阻塞的效果:
script1.jpg
最后的请求被前两个请求阻塞 

  每个请求需要花费1.5秒的时间。很明显,第三个请求必须等到第一个请求结束之后才能执行,因此总共需要进行3秒多钟才能执行完毕。我们要改变的就是这个状况。 

传统的跨域名异步请求解决方案
  AJAX安全性的唯一保证,似乎就是对于跨域名(Cross-Domain)AJAX请求 的限制。除非打开本地硬盘的网页,或者在IE中将跨域名传输数据的限制打开,否则向其他域名发出AJAX请求都会被禁止。而且对于跨域名的判断非常严格, 不同的子域名,或者相同域名的不同端口,都会被认作是不同的域名,我们不能向它们的资源发出AJAX请求。

  从表面上看起来似乎没有办法打破这个限制,还好我们有个救星,那就是iframe!

  iframe虽然不在标准中出现,但是由于它实在有用,FireFox也“不得不”对它进 行了支持(类似的还有innerHTML)。网上已经有一些跨域名发出异步请求的做法,但是它们实在做的不好。它们的简单工作原理如下:在另一个域名下放 置一个特定的页面文件作为Proxy,主页面将异步请求的信息通过Query String传递入iframe里的Proxy页面,Proxy页面在AJAX请求执行完毕后将结果放在自己location的hash中,而主页面会对 iframe的src的hash值进行轮询,一旦发现它出现了改变,则通过hash值得到需要的信息。

  这个方法的实现比较复杂,而且功能有限。在 IE和FireFox中,对于URL的长度大约可以支持2000个左右的字符。对于普通的需求它可能已经足够了,可惜如果真要传递大量的数据,这就远远不 够了。与我们一会儿要提出的解决方案相比,可能它唯一的优势就是能够跨任意域名进行异步请求,而我们的解决方案只能突破子域名的限制。

  那么现在来看看我们的做法!

 

优雅地突破子域名的限制

  我们突破子域名限制的关键还是在于iframe。

  iframe是的好东西,我们能够跨过子域名来访问iframe里的页面对象,例如 window和DOM结构,包括调用JavaScript(通过window对象)——我们将内外页面的 document.domain设为相同就可以了。然后在不同子域名的页面发起不同的请求,把结果通过JavaScript进行传递即可。唯一需要的也仅 仅是一个简单的静态页面作为Proxy而已。

  我们现在就来开始编写一个原形,虽然简单,但是可以说明问题。

  首先,我们先来编写一个静态页面,作为放在iframe里的Proxy,如下:

SubDomainProxy.html 
复制代码 代码如下:

<html xmlns=“http://www.w3.org/1999/xhtml” > 
<head> 
    <title>Untitled Page</title> 
    <script type=“text/javascript” language=“javascript”> 
        document.domain = “test.com“;        function sendRequest(method, url) 
        { 
            var request = new XMLHttpRequest(); 
            request.open(method, url); 
            request.send(null); 
        } 
    </script> 
</head> 
<body> 
</body> 
</html> 


 

  然后我们再编写我们的主页面:


http://www.test.com/Default.html 

复制代码 代码如下:

<html xmlns=“http://www.w3.org/1999/xhtml” > 
<head runat=“server”>  
    <title>Untitled Page</title>  
    <script type=“text/javascript” language=“javascript”>  
        document.domain = “test.com“;        function simpleRequest()  
        {  
            var request = new XMLHttpRequest();  
            request.open(”POST“, “Script.ashx“);  
            request.send(null);  
        } 
function crossSubDomainRequest()  
        {  
            var proxy = document.getElementById(”iframeProxy“).contentWindow;  
            proxy.sendRequest(''POST'', ‘http://sub0.test.com/Script.ashx‘);  
        } 
function threeRequests()  
        {  
            simpleRequest();  
            simpleRequest();  
            crossSubDomainRequest();  
        }  
    </script> 
</head> 
<body>  
    <input type=“button” value=“Request” onclick=“threeRequests()” />  
    <iframe src=“http://sub0.test.com/SubDomainProxy.html” style=“display:none;”  
        id=“iframeProxy”></iframe> 
</body> 
</html> 
   当执行threeRequests方法时,将会同时请求http://www.test.com以及http://sub0.test.com两个不同域名下的资源。很明显,最后一个请求已经不会受到前两个请求的阻塞了:
script2.jpg
不同域名的请求不会被阻塞

  令人满意的结果!

  虽说只能突破子域名,但是这已经足够了,不是吗?我们为什么要强求任意域名之间能够异步通 讯呢?更何况我们的解决方案是多么的优雅!在下一篇文章中,我们将会为ASP.NET AJAX客户端实现一个完整的CrossSubDomainRequestExecutor,它会自动判断是否正在发出跨子域名的请求,并选择AJAX请 求的方式。这样,客户端的异步通讯层就会对开发人员完全透明。世上还会有比这更令人愉快的事情吗?:)

 注意事项

  可能以下几点值得一提:

我在出现这个想法之后也作了一些尝试,最后发现创建XMLHttpRequest对象,调用open方法和send方法都必须在iframe中的页面中执行才能够在IE和FireFox中成功发送AJAX请求。

在上面的例子中,我们向子域名请求的的路径是http://sub0.test.com/Script.ashx。请注意,完整的子域名不可以省略,否则在FireFox下就会出现权限不够的错误,在调用open方法时就会抛出异常——似乎FireFox把它当作了父页面域名的资源了。
因为浏览器的安全策略,浏览器不允许不同域(比如:phinest.org和lab.phinest.org)、不同协议(比如: http://phinest.org和https://phinest.org)、不同端口(比如:http: phinest.org和http://phinest.org:8080)下的页面通过XMLHTTPRequest相互访问,这个问题同样影响着不同页面的Javascript的相互调用和控制,但是当主域、协议、端口相同时,通过设置页面的document.domain主域, Javascript可以在不同的子域名间访问控制,比如通过设置document.domain=''phinest.org'',http: //phinest.org和http://lab.phinest.org页面可互访,这个特性也提供了此情况下不同子域名下的 XMLHTTPRequest相互访问的解决方案。

对于主域、协议、端口相同时的Ajax跨域问题,很早就有设置document.domain来解决的说法,但一直没有看到具体的成功应用,这次尝试了一下,其原理就是,利用一个隐藏的iframe引入所跨另一子域的页面作为代理,通过Javascript来控制iframe引入的另一子域的 XMLHTTPRequest来进行数据获取。对于不同主域/不同协议/不同端口下的Ajax访问需要通过后台的代理来实现。

您可能感兴趣的文章:

ajax post 跨域访问

ajax post 跨域访问

 
PHP:
header('Access-Control-Allow-Origin:*'); header('Access-Control-Allow-Methods:POST,GET'); header('Access-Control-Allow-Credentials:true'); 
js:
$.ajax({ type: 'POST', url'https://to.com/postHere.PHP' crossDomain true data'{"some":"json"}' dataType'json' successfunction(responseData textStatus jqXHR) {var value = responseDatasomeKey;},0)"> errorfunction errorThrown alert('POST Failed.');}});

ajax 跨域访问

ajax 跨域访问

protected void doGet(HttpServletRequest request,HttpServletResponse response) throws servletexception,IOException { // Todo Auto-generated method stub response.setHeader("Access-Control-Allow-Origin","*");//在这个位置一定要加这个要不然悲剧啦

Ajax 跨域访问 tomcat 下的 web service

Ajax 跨域访问 tomcat 下的 web service

Ajax 跨域访问 tomcat 下的 web service

当用 Ajax 跨域访问发布在 Tomcat 下的 web service时,会出现如下的错误。

XMLHttpRequest cannot loadhttp://localhost:8081/DistServices/services/FolderService/GetAllFolderTypes. No 'Access-Control-Allow-Origin'header is present on the requested resource. Origin 'http://localhost:9206' istherefore not allowed access。

这个问题的产生是由于跨域访问时,request 来自的域(http://localhost:9206)不在服务(http://localhost:8081)所接受的域列表里面。说人话就是,哥的服务不是你想要就要得,没经过我的批准,你没法使用。就好像你去按摩店:"老板,来个漂亮妹子给我按摩。"。你想要这些服务,不给钱是不行的。

因此,要是想跨域访问这个服务,我们得经过服务发布者(老板)的允许,将我们发起请求的域加到服务器允许访问的域列表里面。问题知道了,那怎么做呢?

从上面的描述可以看出,工作主要在服务端,只要服务发布者允许,请求者就可以正常访问了,因此服务发布者需要做一些工作来达到这个目的。

CORS介绍

跨域资源共享(CORS)是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源。而这种访问是被同源策略所禁止的。CORS系统定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。。

简言之,CORS就是为了让AJAX可以实现可控的跨域访问而生的。

Tomcat下的配置

下载cors-filter-2.3.jar(其它版本也可),java-property-utils-1.9.jar这两个库文件,放到lib目录下。工程项目中web.xml中的配置如下:

1、加载 CORSFilter

<filter>

<filter-name>CORS</filter-name>

<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>

</filter>

如果需要动态监测过滤规则的变化,那么应该使用如下的配置代替上面的配置(实际上就是使用另外一种类型的CORSFilter):

<filter>

<filter-name>CORS</filter-name>

<filter-class>com.thetransactioncompany.cors.autoreconf.AutoReconfigurableCORSFilter</filter-class>

</filter>

2、指定规则

如果只允许来自某个域(http://localhost:9206)的请求,那么给CORSFilter加如下参数:

<init-param>

<param-name>cors.allowOrigin</param-name>

<param-value>http://localhost:9206</param-value>

</init-param>

如果允许同时来自两个域(http://localhost:9206 和 http://chenyp.com)的请求,那么给CORSFilter加如下参数:

<init-param>

<param-name>cors.allowOrigin</param-name>

<param-value>http://localhost:9206,http://chenyp.com</param-value>

</init-param>

如果允许来自任何域的请求,那么给CORSFilter加如下参数:

<init-param>

<param-name>cors.allowOrigin</param-name>

<param-value>*</param-value>

</init-param>

其它可配的参数还有:

<init-param>

<param-name>cors.supportedMethods</param-name>

<param-value>GET,POST,HEAD,PUT,DELETE</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>

<param-value>Set-Cookie</param-value>

</init-param>

<init-param>

<param-name>cors.supportsCredentials</param-name>

<param-value>true</param-value>

</init-param>

如果不清楚这些参数所代表的意义,那么你可能需要了解下HTTP请求报文。

3、指定需要过滤的请求

如果只对某个servlet 过滤,那么如下配置:

<filter-mapping>

<filter-name>CORS</filter-name>

<servlet-name>MyServlet</servlet-name>

</filter-mapping>

如果需要对所有的请求过滤,那么如下配置:

<filter-mapping>

<filter-name>CORS</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

这就是所有的配置了,一个完整的配置可能如下:

<filter>

<filter-name>CORS</filter-name>

<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>

<init-param>

<param-name>cors.allowOrigin</param-name>

<param-value>*</param-value>

</init-param>

<init-param>

<param-name>cors.supportedMethods</param-name>

<param-value>GET,DELETE</param-value>

</init-param>

<init-param>

<param-name>cors.supportedHeaders</param-name>

<param-value>Accept,Last-Modified</param-value>

</init-param>

<init-param>

<param-name>cors.exposedHeaders</param-name>

<param-value>Set-Cookie</param-value>

</init-param>

<init-param>

<param-name>cors.supportsCredentials</param-name>

<param-value>true</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>CORS</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

除了这种类型的 CORSFilter ,Apache也提供了用于同样目的的CORSFilter类,原理和配置大同小异,有兴趣的可以看这里:http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html#CORS_Filter

既然是一个Filter,那么我们自己也是可以编写对应的CORSFilter 类的,我在这里编写一个最简单的 CORSFilter:

public class CORSFilter implements Filter {

private FilterConfig _CONfig=null;

@Override

public void init(FilterConfig filterConfig) throws servletexception {

_CONfig=filterConfig;

}

@Override

public void doFilter(ServletRequest request,ServletResponse response,

FilterChain chain) throws IOException,servletexception {

if (_CONfig!=null){

Enumeration names = _CONfig.getinitParameterNames();

String name=null;

String value=null;

while (names.hasMoreElements()){

name=(String)names.nextElement();

value=_CONfig.getinitParameter(name);

((HttpServletResponse)response).addHeader(name,value);

}

}

chain.doFilter(request,response);

}

@Override

public void destroy(){

_CONfig=null;

}

}

对应的配置如下:

<filter>

<filter-name>CORSFilter</filter-name>

<filter-class>dist.filter.CORSFilter</filter-class>

<init-param>

<param-name>Access-Control-Allow-Origin</param-name>

<param-value>*</param-value>

</init-param>

<init-param>

<param-name>Access-Control-Allow-Headers</param-name>

<param-value>Origin,Accept</param-value>

</init-param>

<init-param>

<param-name>Access-Control-Allow-Methods</param-name>

<param-value>GET,DELETE</param-value>

</init-param>

<!--还可以继续配置其它参数-->

</filter>

<filter-mapping>

<filter-name>CORSFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

不足之处,烦请指正!!

关于javaweb 中 ajax 跨域访问实例javaweb跨域请求的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于AJAX javascript的跨域访问执行、ajax post 跨域访问、ajax 跨域访问、Ajax 跨域访问 tomcat 下的 web service的相关信息,请在本站寻找。

本文标签:

上一篇Django--- 请求、响应(django请求响应流程图)

下一篇Django drf:幂等性(幂等性 redis)