加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

【API设计风格—RESTful】:番外篇:跨域问题(四)

发布时间:2020-12-17 10:15:00 所属栏目:安全 来源:网络整理
导读:问题描述: Ionic serve 在浏览器中调试时IP是:http://localhost:8100 而我的本机的服务端的IP是:http://localhost:8080 所以存在跨域访问的问题。 解决方法 【1】设置response(此处只是了解,最终解决方案在下面) response.setHeader(“Access-Control-

问题描述:

Ionic serve 在浏览器中调试时IP是:http://localhost:8100
而我的本机的服务端的IP是:http://localhost:8080
所以存在跨域访问的问题。

解决方法

【1】设置response(此处只是了解,最终解决方案在下面)

response.setHeader(“Access-Control-Allow-Origin”,“*”);

@RequestMapping(value="/course/{id}",method=RequestMethod.GET)
public @ResponseBody Course GetCourse(@PathVariable("id") String courseid,HttpServletResponse response){        
    Course course=new Course();
    course.setId(courseid);
    //course.setCode(coursecode);
    course.setCourseName("高等数学");
    response.setHeader("Access-Control-Allow-Origin","*"); //允许哪些url可以跨域请求到本域
    return course;
}

此种解决方法缺点:这样的话,每个方法都得传入HttpServletResponse作为一个参数
改进:使用拦截器
拦截器定义

public class ResponseInterceptor implements HandlerInterceptor {    

    public boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object obj) throws Exception {
        response.setHeader("Access-Control-Allow-Origin","*"); //设置允许哪些url可以跨域请求到本域,*表示所有
        return true;
    }
    public void postHandle(HttpServletRequest request,Object obj,ModelAndView mv) throws Exception { 

    }
    public void afterCompletion(HttpServletRequest request,Exception ex)
        throws Exception {
        // TODO Auto-generated method stub

    }
}

拦截器配置(在springMVC.xml中)

<!--拦截器配置 -->
    <mvc:interceptors>
        <!--自定义拦截器,用于允许跨域访问 -->
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.tgb.itoo.interceptor.ResponseInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

问题:除了GET请求可以跨域访问外,POST和DELETE请求仍然不可以跨域访问
错误提示
XMLHttpRequest cannot load Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
解释
a. 对于简单请求,如GET,只需要在HTTP Response后添加Access-Control-Allow-Origin。
b. 对于非简单请求,比如POST、PUT、DELETE等,浏览器会分两次应答。第一次preflight(method: OPTIONS),主要验证来源是否合法,并返回允许的Header等。第二次才是真正的HTTP应答。所以服务器必须处理OPTIONS应答。
这对此问题的解决办法

save: {method:'POST',isArray:false,headers: {'Content-Type': 'application/x-www-form-urlencoded'}},

但是这表示你向服务端传递的数据不是JSON格式的,这不符合咱们的需求,而且DELETE请求仍然不可以跨域访问。
参考资料:http://www.52php.cn/article/p-dsqvmmtq-yn.html

2.设置代理服务器(最终解决方案)

注意,这些设置只有通过ionic serve 和 ionic run -l 运行应用才需要

整体说明

1.首先我们需要在 ionic.project文件中设置我们的代理,这会告诉我们的 Ionic 本地服务器监听这些地址,然后发送这些请求到我们的目标地址上。
2.在我们的应用中,当运行 serve 或 run -l 时候,我们需要把要访问的结点地址替换成代理服务器的地址。
3.使用gulp任务的 replace 模块来转换出口地址会简单一点。
4.建议的方法是设置一个 Angular Constant 来定位到我们试图代理的 API。
这就是我们下面要采用的方法。我们会同时设置一个 Angular Service 来从 API结点 获取数据。

详细流程

设置代理路径

比如说我们想要访问 http://cors.api.com/api,但并不允许我们来自 localhost的 origin。
代理的设置包括两件事儿:在你本地 Ionic 服务器需要访问的 path,最终需要访问API的 proxyUrl。
在你的 ionic.project 中像这样设置:

     

{
  "name": "proxy-example","app_id": "","proxies": [ { "path": "/api","proxyUrl": "http://cors.api.com/api" } ] }

通过ionic serve启动你的服务器

像我们上面指定的这样,当你访问 Ionic 服务器地址 http://localhost:8100/api 的时候,它会以你的名义访问 http://cors.api.com/api。
这样,就不需要 CORS 了。

设置 Angular Constant

把你的 API结点设置成 Angular Constants是非常简单的一件事儿。
下面我们就来把API结点指定成为我们的代理 URL。
之后(发布时候)我们会把正式的地址作为 constant。

angular.module('starter',['ionic','starter.controllers','starter.services'])
.constant('ApiEndpoint',{
  url: 'http://localhost:8100/api'
}) // For the real endpoint,we'd use this // .constant('ApiEndpoint',{ // url: 'http://cors.api.com/api' // })

设置好之后你就能像下面这样在应用中引入ApiEndpoint依赖,随意调用这个constant了。
设置Angular Service

angular.module('starter.services',[])//NOTE: We are including the constant `ApiEndpoint` to be used here.
.factory('Api',function($http,ApiEndpoint) {
  console.log('ApiEndpoint',ApiEndpoint)
var getApiData = function() {
    return $http.get(ApiEndpoint.url + '/tasks')
      .then(function(data) {
        console.log('Got some data: ',data);
        return data;
      });
  };
return {
    getApiData: getApiData
  };
})

通过 Gulp 自动转换地址

这个过程中,我们需要修改gulpfile.js来添加两个任务:添加代理和移除代理。
首先安装replace模块 npm install –save replace

var replace = require('replace');
var replaceFiles = ['./www/js/app.js'];
gulp.task('add-proxy',function() {
  return replace({
    regex: "http://cors.api.com/api",replacement: "http://localhost:8100/api",paths: replaceFiles,recursive: false,silent: false,});
})
gulp.task('remove-proxy',function() {
  return replace({
    regex: "http://localhost:8100/api",replacement: "http://cors.api.com/api",});
})

参考资料:http://ionichina.com/topic/54f051698cbbaa7a56a49f98

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读