【API设计风格—RESTful】:番外篇:跨域问题(四)_ionic serve ip-程序员宅基地

技术标签: 【其他】  跨域  ionic  angularJS  ……【API设计风格】  

问题描述:

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, HttpServletResponse response,
        Object obj, ModelAndView mv) throws Exception { 

    }
    public void afterCompletion(HttpServletRequest request,
        HttpServletResponse response, Object obj, 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://blog.csdn.net/freshlover/article/details/44223467

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",
    paths: replaceFiles,
    recursive: false,
    silent: false,
  });
})

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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u010924834/article/details/50965714

智能推荐

Error: Q0122E :Could not open file 'xxxx.axf': No such file or directory-程序员宅基地

在学习iap的过程中想要生成一个bin文件,发现需要在keil的user选项卡中配置下路径,通过fromelf.exe把xxx.axf转换成xxx.bin。但是采用原子的路径配置方法:D:\tools\mdk5.14\ARM\ARMCC\bin\fromelf.exe(这里替换成自己的keil路径) --bin -o ..\OBJ\xxx.bin ..\OBJ\xxx.axf 发现会报错E...

uiautomatorviewer适配Android 9.0-10.0的方法_uiautomatorviewer安卓9-程序员宅基地

adb push 文件路径/LvmamaXmlKit.jar /data/local/tmp/_uiautomatorviewer安卓9

python 中 list 列表 的十种操作方法:添加,插入,弹出,删除,延长,运算,查找,排序,反转,采用递归函数深度遍历list_python list 延长-程序员宅基地

首先,创建一个list:(a) 用append()在list的末尾添加一个元素:myadd = [1,9,7]myadd.append(5)print(myadd)输出结果为 [1, 9, 7, 5](b) 用insert()在第1位插入元素8:myadd = [1,9,7]myadd.insert(1,8)print(myadd)输出结果为 [1, 8_python list 延长

什么是GIS-程序员宅基地

简单的说,GIS系统将描述位置(地方)的层信息结合在一起,通过这些信息可以使你更好地认识这个位置(地方)。你可以按照需要选择使用哪些层信息,比如找一个更好的地段设立店铺、分析环境危害、通过综合城市中相同的犯罪,发现犯罪类型等等。   GIS系统是将描述“在什么地方”的信息与描述“

【前端】小白上手Promise、Async/Await和手撕代码_宇宙一码平川的博客-程序员宅基地

写在前面对于前端新手而言,Promise是一件比较困扰学习的事情,需要理解的细节比较多。对于前端面试而言,Promise是面试官最常问的问题,特别是手撕源码。众所周知,JavaScript语言执行环境是“单线程”。单线程,就是指一次只能完成一件任务,如果有多个任务就必须排队等候,前面一个任务完成,再执行后面一个任务。这种“单线程”模式执行效率较低,任务耗时长。为了解决这个问题,就有了异步模式,也叫异步编程。一、异步编程所谓"异步",简单说就是一个任务分成两段,先执行第一段,然后转而执行其他任务

【练习/sklearn库基础】使用LinearRegssion、Lasso、Ridge进行回归预测,并计算各模型的评估结果,用条形图显示。_linerregession losso ridge 0.83_NeHAO_WU的博客-程序员宅基地

声明:1、 学生刚开始学习python,代码会有很多不严谨,也较为粗糙,单纯用于广大网友参考,希望能起到一定的帮助2、 如果要转载,请标记出来源3、本文纯粹用于技术练习,请勿用作非法途径4、如果有问题请在评论区指出,虚心接受立马改正做题途中所遇问题:1.在条形图上方标注各个评分值,忘了,搞了老半天搞出来代码块:#1、 导入sklearn库自带的乳腺癌数据集(。load_breast_cancer),使用LinearRegssion、Lasso、Ridge进行回归预测,并计算各模型的评估结果,_linerregession losso ridge 0.83

随便推点

docker 国内镜像 for Mac_国内 docker mac 下载-程序员宅基地

docker pull 国外的镜像很慢docker - >preferences -> Daemon添加https://docker.mirrors.ustc.edu.cnhttps://hub-mirror.c.163.com下载速度就会变的很快 非常的方便!_国内 docker mac 下载

Android Studio按扭的两种事件监听器响应方式_android studio数字事件响应-程序员宅基地

Android Studio按扭的两种事件监听器响应方式演示android按钮的两种响应方式演示。第一步:添加按扭1. 先新建工程** ,File/New/New Project/Empty Activity/next/name:MyDemo1 Language:java Minimum SDK:API17:Android4.2(Jelly Bean) /Finish如图:2.默认HellWold,代码如下:<?xml version="1.0" encoding="utf-8"?>_android studio数字事件响应

VLAN原理详解[转载] 网桥--交换机---路由器_网桥可以划分vlan吗-程序员宅基地

来自:http://blog.csdn.net/phunxm/article/details/9498829一、什么是桥接 桥接工作在OSI网络参考模型的第二层数据链路层,是一种以MAC地址来作为判断依据来将网络划分成两个不同物理段的技术,其被广泛应用于早期的计算机网络当中。 我们都知道,以太网是一种共享网络传输介质的技术,在这种技术下,如果一_网桥可以划分vlan吗

爬取单个B站视频_bin/getstreamurl?videoid=1001_5a63ef09fbc74df6a0ba-程序员宅基地

爬取B站单个视频用到的库有 os,re,requests,lxml直接上源码!!!“”"1.每次爬取都是爬到了 三个文件,现在只想要合成好的MP4文件 再在上一个例子上优化– os.remove()2. 如果想显示文件的大小。。。。–1,发送请求的时候,参数添加上 steam=True“”"import requestsimport osfrom lxml import etreeimport reif name == ‘main’:# 1.确认urlurl_ = input(_bin/getstreamurl?videoid=1001_5a63ef09fbc74df6a0bab9c2ddcf8fe6

xdma_xdma 驱动连读连写-程序员宅基地

xilinx xdma Linux 驱动 使用xilinx 官网下载的linux xdma 驱动,在按照他们给的提示编译的时候会出现,一些问题编译的时候,会出现证书的问题,官方说不用管,插入内核的时候也会有一些错误。int xdma_cdev_init(void){ g_xdma_class = class_create(THIS_MODULE, XDMA_NODE_NAME);..._xdma 驱动连读连写

sox常用命令整理_sox命令-程序员宅基地

play *.wav 播放音频 sox *.wav -n stat:查看文件信息 sox *.wav -n stat -v:不失真最大调整量 sox -v 0.8 input.wav output.wav:调整音量0.8,(大于1为扩大) sox *.wav *1.wav trim 0 10:截取0秒开始,10秒长度的音频 sox *.wav sox *.m..._sox命令