mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-27 08:02:01 +00:00
Merge pull request #2265 from clarkdo/external_url
feat: allow redirect to external url
This commit is contained in:
commit
887ebd5e25
@ -7,6 +7,9 @@ export default {
|
|||||||
name: 'nuxt',
|
name: 'nuxt',
|
||||||
props: ['nuxtChildKey'],
|
props: ['nuxtChildKey'],
|
||||||
render(h) {
|
render(h) {
|
||||||
|
if (this.nuxt._redirected) {
|
||||||
|
return h('div', [ 'redirecting.' ])
|
||||||
|
}
|
||||||
// If there is some error
|
// If there is some error
|
||||||
if (this.nuxt.err) {
|
if (this.nuxt.err) {
|
||||||
return h('nuxt-error', {
|
return h('nuxt-error', {
|
||||||
|
@ -132,11 +132,23 @@ export async function setContext(app, context) {
|
|||||||
path = status
|
path = status
|
||||||
status = 302
|
status = 302
|
||||||
}
|
}
|
||||||
|
if (path.charAt(0) === '/' && path.charAt(1) !== '/') {
|
||||||
app.context.next({
|
app.context.next({
|
||||||
path: path,
|
path: path,
|
||||||
query: query,
|
query: query,
|
||||||
status: status
|
status: status
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
path = formatUrl(path, query)
|
||||||
|
if (process.server) {
|
||||||
|
app.context.res.setHeader('Location', path)
|
||||||
|
app.context.res.statusCode = status
|
||||||
|
app.nuxt._redirected = true
|
||||||
|
}
|
||||||
|
if (process.client) {
|
||||||
|
window.location = path
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (process.server) app.context.beforeNuxtRender = (fn) => context.beforeRenderFns.push(fn)
|
if (process.server) app.context.beforeNuxtRender = (fn) => context.beforeRenderFns.push(fn)
|
||||||
if (process.client) app.context.nuxtState = window.__NUXT__
|
if (process.client) app.context.nuxtState = window.__NUXT__
|
||||||
@ -442,3 +454,60 @@ function escapeString(str) {
|
|||||||
function escapeGroup(group) {
|
function escapeGroup(group) {
|
||||||
return group.replace(/([=!:$\/()])/g, '\\$1')
|
return group.replace(/([=!:$\/()])/g, '\\$1')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format given url, append query to url query string
|
||||||
|
*
|
||||||
|
* @param {string} url
|
||||||
|
* @param {string} query
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
function formatUrl (url, query) {
|
||||||
|
let protocol
|
||||||
|
let index = url.indexOf('://')
|
||||||
|
if (index !== -1) {
|
||||||
|
protocol = url.substring(0, index)
|
||||||
|
url = url.substring(index + 3)
|
||||||
|
} else if (url.indexOf('//') === 0) {
|
||||||
|
url = url.substring(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
let parts = url.split('/')
|
||||||
|
let result = (protocol ? protocol + '://' : '//') + parts.shift()
|
||||||
|
|
||||||
|
let path = parts.filter(Boolean).join('/')
|
||||||
|
let hash
|
||||||
|
parts = path.split('#')
|
||||||
|
if (parts.length === 2) {
|
||||||
|
path = parts[0]
|
||||||
|
hash = parts[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
result += path ? '/' + path : ''
|
||||||
|
|
||||||
|
if (query && JSON.stringify(query) !== '{}') {
|
||||||
|
result += (url.split('?').length === 2 ? '&' : '?') + formatQuery(query)
|
||||||
|
}
|
||||||
|
result += hash ? '#' + hash : ''
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform data object to query string
|
||||||
|
*
|
||||||
|
* @param {object} query
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
function formatQuery (query) {
|
||||||
|
return Object.keys(query).sort().map(key => {
|
||||||
|
var val = query[key]
|
||||||
|
if (val == null) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
if (Array.isArray(val)) {
|
||||||
|
return val.slice().map(val2 => [key, '=', val2].join('')).join('&')
|
||||||
|
}
|
||||||
|
return key + '=' + val
|
||||||
|
}).filter(Boolean).join('&')
|
||||||
|
}
|
||||||
|
@ -143,6 +143,15 @@ test('/redirect2', async t => {
|
|||||||
t.is(await page.$text('h1'), 'Index page')
|
t.is(await page.$text('h1'), 'Index page')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('/redirect3', async t => {
|
||||||
|
// New page for redirecting to external link.
|
||||||
|
const page = await browser.page(url('/'))
|
||||||
|
await page.nuxt.navigate('/redirect3', false)
|
||||||
|
await page.waitForFunction(() => window.location.href === 'https://nuxtjs.org/')
|
||||||
|
page.close()
|
||||||
|
t.pass()
|
||||||
|
})
|
||||||
|
|
||||||
test('/no-ssr', async t => {
|
test('/no-ssr', async t => {
|
||||||
await page.nuxt.navigate('/no-ssr')
|
await page.nuxt.navigate('/no-ssr')
|
||||||
|
|
||||||
|
@ -117,6 +117,19 @@ test('/redirect -> check redirected source', async t => {
|
|||||||
t.true(html.includes('<h1>Index page</h1>'))
|
t.true(html.includes('<h1>Index page</h1>'))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('/redirect -> external link', async t => {
|
||||||
|
const headers = {}
|
||||||
|
const { html } = await nuxt.renderRoute('/redirect3', {
|
||||||
|
res: {
|
||||||
|
setHeader(k, v) {
|
||||||
|
headers[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.is(headers.Location, 'https://nuxtjs.org')
|
||||||
|
t.true(html.includes('<div>redirecting.</div>'))
|
||||||
|
})
|
||||||
|
|
||||||
test('/special-state -> check window.__NUXT__.test = true', async t => {
|
test('/special-state -> check window.__NUXT__.test = true', async t => {
|
||||||
const window = await nuxt.renderAndGetWindow(url('/special-state'))
|
const window = await nuxt.renderAndGetWindow(url('/special-state'))
|
||||||
t.is(window.document.title, 'Nuxt.js')
|
t.is(window.document.title, 'Nuxt.js')
|
||||||
|
11
test/fixtures/basic/pages/redirect3.vue
vendored
Normal file
11
test/fixtures/basic/pages/redirect3.vue
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<template>
|
||||||
|
<div>Redirecting...</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
fetch({ redirect }) {
|
||||||
|
return redirect('https://nuxtjs.org/')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
Loading…
Reference in New Issue
Block a user