整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

ajax跨域问题(三种解决方案)

ajax跨域问题(三种解决方案)

什么会出现跨域

  • 跨域问题来源于JavaScript的同源策略,即只有 协议+主机名+端口号 (如存在)相同,则允许相互访问。也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。跨域问题是针对JS和ajax的,html本身没有跨域问题,比如a标签、script标签、甚至form标签(可以直接跨域发送数据并接收数据)等



如何解决跨域问题

  • JSONP
  • JSONP是JSON with Padding的略称。它是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。关于jsonp的使用方式,可以参考http://blog.csdn.net/alen1985/article/details/6365394,优缺点可以参考http://blog.csdn.net/z69183787/article/details/19191385
  • 添加响应头,允许跨域
  • addHeader(‘Access-Control-Allow-Origin:*’);//允许所有来源访问
  • addHeader(‘Access-Control-Allow-Method:POST,GET’);//允许访问的方式
  • 代理的方式
  • 服务器A的test01.html页面想访问服务器B的后台action,返回“test”字符串,此时就出现跨域请求,浏览器控制台会出现报错提示,由于跨域是浏览器的同源策略造成的,对于服务器后台不存在该问题,可以在服务器A中添加一个代理action,在该action中完成对服务器B中action数据的请求,然后在返回到test01.html页面。

Demo1(添加允许跨域请求的响应头)

  • html页面


  • Web后台

  • 按照上面的访问,由于127.0.0.1:8080和localhost:8081的域和端口不同,所以同样会出现跨域问题。


现在用添加响应头的方式


Demo2(jsonp的callback方式)

这里演示的是jquery的ajax,后台采用的是webservice接口形式

注意此时的dataType为jsonp格式,看看后台的接收

我们返回的其实就是一个函数的调用文本,这里注意,callback的名称,由于前台没有指定callback函数,所以这里自动生成了,如果想自定义回调函数名称如下操作,添加一行请求参数

这样后台的回调函数名就变成了mytest

浏览器发出的请求格式和响应数据如下,其实就是返回函数的调用,而需要返回的数据则以函数参数值的形式填入

此时控制台就能够获取到“hello world”

己做网站的时候,经常遇到跨域问题,下面是平时多次实践总结出的解决方法,大家有什么更好的思路,可以相互交流下~XMLHttpRequest cannot load http://www.imooc.com/data/check_f.php. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '[http://localhost:8080](http://localhost:8080/)' is therefore not allowed access.解决方法:跨源问题,添加cors。1.filter或者servlet里面添加response.setHeader("Access-Control-Allow-Origin", "");2.response.setHeader("Access-Control-Allow-Origin", "");放到接收客户端api 的地方3.如果是servlet的话就放到get或者post方法里面,jsp页面就扔到第一行4.如果是filter部署就扔到dofilter()

---------------------------------springmvc---------------------------------

添加SimpleCORSFilter.java

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 SimpleCORSFilter implements Filter {
 public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
 HttpServletResponse response=(HttpServletResponse) res;
 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");
 //response.setHeader("Access-Control-Allow-Headers", "Content-Type");
 // response.setContentType("text/html;charset=UTF-8");
 // response.setHeader("Access-Control-Allow-Origin", "*");
 // response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
 // response.setHeader("Access-Control-Max-Age", "0");
 // response.setHeader("Access-Control-Allow-Headers", "Authentication, Origin, Accept, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, token");
 // response.setHeader("Access-Control-Allow-Credentials", "true");
 // response.setHeader("XDomainRequestAllowed","1");
 chain.doFilter(req, res);
 }
 public void init(FilterConfig filterConfig) {}
 public void destroy() {}
}

web.xml添加

<filter>
 <filter-name>SimpleCORSFilter</filter-name>
 <filter-class>com.zhcs.context.SimpleCORSFilter</filter-class>
</filter>
<filter-mapping>
 <filter-name>SimpleCORSFilter</filter-name>
 <url-pattern>/app/*</url-pattern>
</filter-mapping>

--------------------------------------OR-------------------------------------

添加 CorsConfigureAdapter.java

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
@EnableWebMvc
public class CorsConfigureAdapter extends WebMvcConfigurerAdapter {
 @Override
 public void addCorsMappings(CorsRegistry registry) {
 super.addCorsMappings(registry);
 registry.addMapping("/**");
 }
}

在Controller上或方法上使用@CrossOrigin注解

@CrossOrigin(maxAge=3600)

--------------------------------------xml-------------------------------------

<mvc:cors>
 <mvc:mapping path="/**" />
</mvc:cors>
<mvc:cors>
 <mvc:mapping path="/api/**" allowed-origins="http://domain1.com, http://domain2.com" allowed-methods="GET, PUT" allowed-headers="header1, header2, header3" exposed-headers="header1, header2" allow-credentials="false" max-age="123" />
 <mvc:mapping path="/resources/**" allowed-origins="http://domain1.com" />
</mvc:cors>

--------------------------------------Nginx支持跨域请求--------------------------------------

jax跨域请求:CORS。 CORS又称跨域资源共享,英文全称Cross-Origin Resource Sharing。

假设我们想使用Ajax从a.com的页面上向b.com的页面上要点数据,通 常情况由于同源策略,这种请求是不允许的,浏览器也会返回“源不匹配”的错误,所以就有了“跨域”这个说法。但是我们也有解决办法,我们可以再b.com的页面header信息中增加一行代码:

header(“Access-Control-Allow-Origin: *”);

当我们设置的header为以上信息时,任意一个请求过来之后服务端我们都可以进行处理和响应,那么在调试工具中可以看到其头信息设置, 其中见红框中有一项信息是“Access-Control-Allow-Origin: ”,表示我们已经启用CORS,如果要限制只允许某个域名的请求,可以这样:

$.ajax({

type: “POST”,

data: “random=”+Math.random(),

url: “http://xxx.com/ajax.php“,

dataType: “JSON”,

success: function(data) {

console.log(data); $(“#result_3”).html(data.msg);

},

error: function() {

$(“#result_3”).html(‘Request Error.’); }

});