Jsonpの実現

1689 ワード

Jsonpの実現
jsonpの特徴:scriptを作成してsrcを通じてデータバックを取得し、FuntionName小包データでフロントで設定したFuntionNameメソッドを呼び出します.
/**
 * opts:
 *     - param { String } (callback)
 *     - prefix { String } (__jp)
 *     - name { String } (prefix + incr)
 *     - timeout { Number } (60000)
 * @param  {String}   url     fetch url
 * @param  {Object}   opts    
 * @param  {Function} fn      callback
 */
function originJsonp (url, opts, fn) {
    let prefix = opts.prefix || '__jp'
    let id = opts.name || (prefix + '0')
    let param = opts.param || 'callback'
    let target = document.getElementsByTagName('script')[0] || document.head
    let script

    //   script      
    function clear () {
        if (script.parentNode) {
            script.parentNode.removeChild(script)
        }
        window[id] = {}                
    }

    window[id] = function (data) {
        clear()
        fn && fn(data)
    }

    //      > -1     ~-1 === 0
    url += (~url.indexOf('?') ? '&' : '?') + param + '=' + encodeURIComponent(id);
    url = url.replace('?&', '?');

    script = document.createElement('script')
    script.src = url
    target.parentNode.insertBefore(script, target)
}

function jsonp (url, opts) {
    return new Promise((resolve, reject) => {
        originJsonp(url, opts, (data) => {
            resolve(data)
        })
    })
}

jsonp('https://sug.so.360.cn/suggest?encodein=utf-8&encodeout=utf-8&format=json&fields=word&word=%E6%88%91', {
    'prefix': 'suggest_so'
}).then(res => {
    console.log(res)
})