新浪的oauth第一步会引导用户打开一个页面,然后用户允许后url会重定向到网站根目录下,问题是这样的:
url会带一个code参数,链接会变成XXX.XXX.com/?code=XXXX,不使用htmlMode # $locationProvider.html5Mode(false) 时,route会跳转到XXX.XXX.com/?code=XXXX#/
有没有好的办法能取到这个code的值(现在用的是$window.location.search,因为$location.search在这个模式下没能取到这个值);
有没有好的办法把这个XXX.XXX.com/?code=XXXX#/ ?code=XXX去掉(不去掉的话之后每一个route跳转的链接都会有)
上面的这两个问题我暂时的解决方案是用$window.location.href替换,这样会引起整个页面的刷新(好在是首页登录,
还可以接受,不过总感觉应该有更高级更angularinic的用法)
测试地址 http://llovebaimuda.herokuapp.com/ http://llovebaimuda.herokuapp.com/#/login
不用html5mode是因为如果直接输入url(例如:http://llovebaimuda.herokuapp.com/phone)会导致404,输入
http://llovebaimuda.herokuapp.com/#/phone虽然浏览器显示http://llovebaimuda.herokuapp.com/phone,但是
把url copy给朋友的时候就会404了,除非加上#/,这个问题在angular和后端有什么好的解决方案么
angular有没有办法直接在页面里面使用<script></script>,例如新浪微博登录的组件是个js,他会在页面载入
后对一个dom做一些处理,angular对dom的操作是在directive,然后经过编译-链接巴拉巴拉,总之就是新浪的登录js widget
不能用,还是说angular需要特殊的处理。
angular中oauth又没有比较成熟可复用的东西(中国的例如新浪微博,qq,豆瓣),https://oauth.io/这个木有微博啊
oauth需要下面这几步:
1. 引导用户授权获取code
2. 主动向oauth的网站发起请求,获取access_token
这一步对用户应该是透明的,现在我的想法是让页面主动跳转到一个有authService的页面中,这个authService主动来获取需要用到的数据,然后把access_token
以及user存到$routeScope(有没有类似backbone的localstorage?)中,这个操作无论成功与否都要跳转到下一个页面,这就是登录成功才能看到的页面
if 'code' of param_dict
$window.location.href = href + '#' + DEFAULT_URL
'use strict'https://oauth.io/
STATIC_URL = '/static'
DEFAULT_URL = '/phones'
phonecatApp = angular.module('phonecatApp', [
'ngRoute'
'ConfigServices'
'phonecatControllers'
'authControllers'
'phonecatServices'
'phonecatFilters'
'phonecatAnimations'
])
phonecatApp.config([
'$routeProvider'
'$locationProvider'
($routeProvider, $locationProvider, config) ->
$routeProvider
.when('/',{})
.when('/login',{
templateUrl: STATIC_URL + '/partials/auth/login.html'
controller: 'LoginCtrl'
})
.when('/auth/:code',{
})
.when('/phones', {
templateUrl: STATIC_URL + '/partials/phone/list.html'
controller: 'PhoneListCtrl'
})
.when('/phones/:phoneId', {
templateUrl: STATIC_URL + '/partials/phone/detail.html'
controller: 'PhoneDetailCtrl'
})
# Catch all
.otherwise({redirectTo: 'DEFAULT_URL'})
# Without server side support html5 must be disabled.
$locationProvider.html5Mode(false)
])
parse_query_dict = (query) ->
query = query.trim()
if query.length <= 1
return {}
query = query.substring(1)
query_dict = {}
list = query.split('&')
for q in list
k_v = q.split('=')
query_dict[k_v[0]] = k_v[1]
return query_dict
phonecatApp.run([
'$rootScope'
'$route'
'$location'
'$window'
($rootScope, $route, $location, $window) ->
$rootScope.$on('$locationChangeStart', (event, next, current) ->
if not $rootScope.user
if $location.path() == '/'
params = $window.location.search
if params
href = $window.location.href
href = href.replace(params,'')
param_dict = parse_query_dict(params)
if 'code' of param_dict
$window.location.href = href + '#' + DEFAULT_URL
# no logged user, we should be going to #login
if next.templateUrl == "partials/login.html"
# already going to #login, no redirect needed
else
# not going to #login, we should redirect now
#$location.path "/login"
)
])
我来回答一下第一个问题:
要去掉 ?code=XXX,用 location.href 肯定会刷新页面的,使用 window.pushState 才对。
参考:MDN: 操纵浏览器的历史记录
angularjs 新浪微博跨域解决办法