JavaScript 关于 angular 调用接口跨域的一些问题

wikimo · 2015年07月22日 · 最后由 nightire 回复于 2015年09月07日 · 6129 次阅读

angular 在调用接口的时候涉及到了跨域问题。

场景描述:

  1. 接口获取验证码;
  2. 接口注册用户并带上步骤 1 中获取的验证码;

需要如何保持一个 session 的,目前是用户注册提示验证码错误,感觉是在调用注册接口的过程中重新发起了会话导致验证码不一致。 尝试设置了 withCredentials,但是报错了,没有效果,请教下,需要解决的问题就是获取验证码,通过验证码进行用户注册。

$httpProvider.defaults.withCredentials = true;

其实你的描述还很模糊,很多关键点你都没说你那里的实现是怎样,感觉你对这个事儿的概念并不是很清楚。先看看这一段是否对你理解这个问题有帮助吧:https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials

重点是你得搞清楚加上 withCredentials 到底做了什么,在什么情况下有用?解决跨域共享问题有哪些可能的方案,你那里用了什么?“感觉 session 不一致”,怎么“感觉”的?有没有打开开发者工具验证一下?有没有针对这一情况由后端提供统一 session 的机制?

总之,不要因为用了 angular 就把类似问题特殊化,总觉得好像是因为 angular 怎样才出现的问题,这是关于 HTTP/Browser 的 common issue,无论用不用 angular 都会遇到的。

你可以本地用 Nginx 代理来实跨域访问

upstream local_front_service{
  server localhost:3000;
}

server {
  listen 80;
  server_name localhost;

  location ^~ /api { # 换成你 API 的 path 前缀等
    proxy_pass http://remote_service; #这里换成你的后端服务
  }

  location ^~ /browser-sync { #如果你用了 browser-sync 可以加下这个配置
    proxy_pass        http://fusion_test_front;
    proxy_http_version 1.1;
    proxy_set_header  Upgrade $http_upgrade;
    proxy_set_header  Connection "upgrade";
  }

  location / {
    proxy_pass        http://local_front_service;
  }
}

#2 楼 @miclle 如果是本地开发的话完全用不着 Nginx,直接加一个 node 的 proxy middleware 就好了。

一个使用 gulp+browserSync 的例子:

gulp.task('serve', function() {
    var proxyAPIMiddleware = proxy(
        _.assign(url.parse(options.proxyAPIURL), options.proxyAPI)
    )

    options.browserSync.server.middleware.push(proxyAPIMiddleware)
    browserSync(options.browserSync)
})

对应的 options:

browserSync: &browserSync
  ui: false
  files:
    - "public/**"
    - "!public/**/*.map"
  server:
    baseDir: "public"
    middleware: []
  host: "127.0.0.1"
  port: 9000
  open: false
  notify: false
  online: true

proxyAPIURL: "这里是你要代理的目标地址"
proxyAPI: &proxyAPI
  route: "这里是本地请求地址"
  via: false
  cookieRewrite: false
  reserveHost: true

#3 楼 @nightire 我再试试,之前这样折腾没搞出来

@nightire @miclle 谢谢回复

  • 提供的资料之前也看了几遍的,对跨域的几种方法也了解;

  • 后端不在自己手里,不方便进行各种调试,所以“感觉”这说法是自己通过一些工具测试以及个人经验判断的;

  • 表达的意思我也明白了,本质上不是 angular 的问题,而是对于 http 的一些基本问题;

  • 另外这种 proxy 的方式学习了;

  • 最后与后端沟通换了方案解决了,api 应该是无状态的,可能提供的上下文信息也太少,大家无法很好地判断问题;

#3 楼 @nightire 我用 grunt+browserSync 也遇到了跨域的问题,能帮忙解决吗?

#6 楼 @chenjiufu Grunt 和我上面用 gulp 的例子没有本质区别

感觉您 @nightire 对前端相关研究的比较深入,对 vue.js 应该也了解吧,怎么看?

#8 楼 @wikimo 没什么特别的看法,想用就用咯,就是个工具罢了,用谁不是用啊。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号