mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-23 14:15:13 +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',
|
||||
props: ['nuxtChildKey'],
|
||||
render(h) {
|
||||
if (this.nuxt._redirected) {
|
||||
return h('div', [ 'redirecting.' ])
|
||||
}
|
||||
// If there is some error
|
||||
if (this.nuxt.err) {
|
||||
return h('nuxt-error', {
|
||||
|
@ -132,11 +132,23 @@ export async function setContext(app, context) {
|
||||
path = status
|
||||
status = 302
|
||||
}
|
||||
if (path.charAt(0) === '/' && path.charAt(1) !== '/') {
|
||||
app.context.next({
|
||||
path: path,
|
||||
query: query,
|
||||
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.client) app.context.nuxtState = window.__NUXT__
|
||||
@ -442,3 +454,60 @@ function escapeString(str) {
|
||||
function escapeGroup(group) {
|
||||
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')
|
||||
})
|
||||
|
||||
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 => {
|
||||
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>'))
|
||||
})
|
||||
|
||||
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 => {
|
||||
const window = await nuxt.renderAndGetWindow(url('/special-state'))
|
||||
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