最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】iOS的Safari中html页面报错:SecurityError: The operation is insecure

Safari crifan 4238浏览 0评论
已经实现了一个基本的页面,加上了保存localStorage的代码:
function storeInput(inputStr){
    console.log("storeInput: inputStr=%s", inputStr)

    localStorage.setItem(LastSearchInputStoreKey, inputStr)
}

function restoreInput(){
    console.log("restoreInput")
    var savedSearchInput = localStorage.getItem(LastSearchInputStoreKey)
    console.log("savedSearchInput=", savedSearchInput)
    return savedSearchInput
}
在Chrome中正常。
但是去Safari中,结果报错:
jQuery.readyException = function( error ) {
    window.setTimeout( function() {
        throw error;
    } );
};
看起来好像是:
var savedSearchInput = localStorage.getItem(LastSearchInputStoreKey)
报错的。
ios safari localStorage.getItem SecurityError
Safari 11 gets SecurityError (DOM exception 18)… |Apple Developer Forums
javascript – Getting Security Error on iPhone when using localStorage – Stack Overflow
javascript – Safari on iOS>=11 block cookies & web storage by default – how to persist (first-party) data? – Stack Overflow
javascript – HTML5 localStorage.setItem is not working on iOS 8 – Safari mobile – Stack Overflow
结论就是:
iOS 11中Safari默认开启了:禁用Cookie
所以还是尽量少用localStorage
localStorage和sessionStorage在ios10下的报错问题 – 简书
Why using localStorage directly is a bad idea – Michal Zalecki
把localStorage改为url中传递参数的写法吧
期间遇到:
【已解决】Bootstrap的js中如何在click事件中传递额外参数
【总结】
此处最后用:
每次传入其他url时,把之前输入参数传递到url中:
book_detail.html?book_id=5bd7bf4cbfaa44fe2c74034e&cur_input=apple
中的&cur_input=apple
然后返回来时,解析后拿到cur_input的值,再传回给:
index.html?cur_input=apple
即可实现。
而详情页进入详情页,则也是:
获取当前的cur_input
继续传入下一层的详情页即可。
从而规避使用,会导致iOS触发安全问题而无法正常使用的,localStorage。
代码:
js/main.js
$(document).ready(function(){
    console.log("main document ready !")
    // console.log($);

    function restoreInputAndSearch(){
        console.log("restoreInputAndSearch")

        var curInputValue = $("#inputQuery").val()
        console.log("curInputValue=%s", curInputValue)

        if (curInputValue){
            ajaxSubmitQuery()
        } else {
            var preSavedInput = restoreInput()
            console.log("preSavedInput=%s", preSavedInput)
            if (preSavedInput) {
                $("#inputQuery").val(preSavedInput)
                console.log("Have restored previous saved search input value: %s", preSavedInput)

                ajaxSubmitQuery()
            }
        }
    }

    restoreInputAndSearch()

    // $(document).on("click", ".single_storybook_item", redirectToDetailPage)
    // $(document).on("click", ".single_storybook_item", {curInput: $("#inputQuery").val()}, redirectToDetailPage)
    function saveInputAndRedirect(event){
        console.log("saveInputAndRedirect: event=%o", event)
        console.log("this=%o", this)

        var curInput = $("#inputQuery").val()
        console.log("curInput=%s", curInput)
        event.data = {
            "curInput": curInput,
            "curElement": this,
        }
        console.log("event.data=%o", event.data)
        // redirectToDetailPage.bind(this)
        redirectToDetailPage(event)
    }
    $(document).on("click", ".single_storybook_item", saveInputAndRedirect)
js/book_common.js
// Query String Key for Current Input (Search) String
const CurrentInputQsKey = "cur_input"


function getQueryVariable(variable) {
    console.log("getQueryVariable: variable=%s", variable)
    var query = window.location.search.substring(1)
    console.log("query=%s", query)
    var vars = query.split('&')
    console.log("vars=%o", vars)
    for (var i = 0; i < vars.length; i++) {
        var pair = vars[i].split('=');
        console.log("pair=%o", pair)
        var decodedPair0 = decodeURIComponent(pair[0])
        console.log("decodedPair0=%s", decodedPair0)
        if (decodedPair0 == variable) {
            var decodedPair1 = decodeURIComponent(pair[1])
            console.log("decodedPair1=%s", decodedPair1)
            return decodedPair1
        }
    }
    console.log('Query variable %s not found', variable);
}

function redirectToDetailPage(event){
    console.log("redirectToDetailPage: event=%o", event)
    console.log("event.data=", event.data)

    // window.location = $(this).data("href")
    var curElement = $(this)
    var curInput = undefined

    if (event.data){
        curElement = $(event.data.curElement)

        curInput = event.data.curInput
    }
    console.log("curElement=", curElement)
    console.log("curInput=", curInput)

    var bookUrl = curElement.find("#book_url").text()
    console.log("bookUrl=", bookUrl)
    var bookId = curElement.find("#book_id").text()
    console.log("bookId=", bookId)
    // window.location = bookUrl
    var bookDetailUrl = "book_detail.html"
    console.log("bookDetailUrl=", bookDetailUrl)
    // localStorage.setItem("cur_book_id", bookId)
    // // for debug
    // var savedBookId = localStorage.getItem("cur_book_id")
    // console.log("savedBookId=", savedBookId)
    // window.location = bookDetailUrl
    var bookDetailUrlWithPara = bookDetailUrl + "?book_id=" + bookId
    if (curInput) {
        var encodedCurInput = encodeURIComponent(curInput)
        console.log("encodedCurInput=%s", encodedCurInput)
        bookDetailUrlWithPara += `&${CurrentInputQsKey}=${encodedCurInput}`
    }
    console.log("bookDetailUrlWithPara=", bookDetailUrlWithPara)
    window.location = bookDetailUrlWithPara
}


// restore previous search input from url
function restoreInput(){
    console.log("restoreInput")

    // var location = window.location
    // console.log("location=%o", location)
    // var search = location.search
    // console.log("search=%s", search)

    var restoredCurInput = getQueryVariable(CurrentInputQsKey)
    console.log("restoredCurInput=", restoredCurInput)
    return restoredCurInput
}
js/book_detail.js
$(document).ready(function(){
    console.log("boot detail document ready !")

    function backToHome(event){
        console.log("backToHome: event=%o", event)
        var homeUrl = "index.html"
        // console.log("homeUrl=", homeUrl)
        // window.location = homeUrl

        var restoredInput = restoreInput()
        console.log("restoredInput=", restoredInput)
        if (restoredInput) {
            homeUrl += `?${CurrentInputQsKey}=${restoredInput}`
        }
        console.log("homeUrl=", homeUrl)
        window.location = homeUrl
    }

    $(document).on("click", "#back_home", backToHome)


    // $(document).on("click", ".single_storybook_item", redirectToDetailPage)
    function tryGetPassedInputAndRedirect(event){
        console.log("tryGetPassedInputAndRedirect: event=%o", event)
        console.log("this=%o", this)

        var curInput = restoreInput()
        console.log("curInput=%s", curInput)
        event.data = {
            "curInput": curInput,
            "curElement": this,
        }
        console.log("event.data=%o", event.data)
        redirectToDetailPage(event)
    }
    $(document).on("click", ".single_storybook_item", tryGetPassedInputAndRedirect)
实现了效果:
首页中搜索结果后:
点击某个书籍进入详情页:
url是:
book_detail.html?book_id=5bd7bdbabfaa44fe2c739dfa&cur_input=apple
包括我希望传入的cur_input=apple
然后点击详情的推荐列表后:
还是进入详情,然后url中仍然能拿到cur_input=apple
然后点击 详情页内部的左上角按钮返回时:
可以把之前输入的参数传递回去:
然后再去进入详情页,点击 浏览器 向左按钮:
-》用于模拟 手机端 返回 cancel按钮:
(如果之前是第一次进入详情页,就 cancel返回的话)
则url中是没有参数的
但是由于输入框中有之前输入的值,则也是可以获取到并触发搜索的:

转载请注明:在路上 » 【已解决】iOS的Safari中html页面报错:SecurityError: The operation is insecure

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
83 queries in 0.166 seconds, using 22.15MB memory