热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

我可以设置WKWebView要使用的cookie吗?-CanIsetthecookiestobeusedbyaWKWebView?

ImtryingtoswitchanexistingappfromUIWebViewtoWKWebView.Thecurrentappmanagestheusers

I'm trying to switch an existing app from UIWebView to WKWebView. The current app manages the users login / session outside of the web view and sets the COOKIEs required for authentication into the the NSHTTPCOOKIEStore. Unfortunately new WKWebView doesn't use the COOKIEs from the NSHTTPCOOKIEStorage. Is there another way to achieve this?

我想把一个现有的应用从UIWebView切换到WKWebView。当前应用程序管理web视图之外的用户登录/会话,并将验证所需的COOKIE设置为NSHTTPCOOKIEStore。不幸的是,新的WKWebView不使用来自NSHTTPCOOKIEStorage的COOKIE。还有其他方法可以实现这一点吗?

11 个解决方案

#1


86  

Edit for iOS 11+ only

只对ios11 +进行编辑

Use WKHTTCOOKIEStore:

使用WKHTTCOOKIEStore:

let COOKIE = HTTPCOOKIE(properties: [
    .domain: "example.com",
    .path: "/",
    .name: "MyCOOKIEName",
    .value: "MyCOOKIEValue",
    .secure: "TRUE",
    .expires: NSDate(timeIntervalSinceNow: 31556926)
])! 

webView.configuration.websiteDataStore.httpCOOKIEStore.setCOOKIE(COOKIE)

Since you are pulling them over from HTTPCookeStorage, you can do this:

因为您正在从HTTPCookeStorage将它们拉过来,所以您可以这样做:

let COOKIEs = HTTPCOOKIEStorage.shared.COOKIEs ?? []
for (COOKIE) in COOKIEs {
    webView.configuration.websiteDataStore.httpCOOKIEStore.setCOOKIE(COOKIE)
}

Old answer for iOS 10 and below

iOS 10和以下的旧答案

If you require your COOKIEs to be set on the initial load request, you can set them on NSMutableURLRequest. Because COOKIEs are just a specially formatted request header this can be achieved like so:

如果您要求在初始加载请求上设置COOKIE,您可以在NSMutableURLRequest上设置它们。因为COOKIE只是一个特殊格式的请求头,所以可以这样实现:

WKWebView * webView = /*set up your webView*/
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/index.html"]];
[request addValue:@"TeskCOOKIEKey1=TeskCOOKIEValue1;TeskCOOKIEKey2=TeskCOOKIEValue2;" forHTTPHeaderField:@"COOKIE"];
// use stringWithFormat: in the above line to inject your values programmatically
[webView loadRequest:request];

If you require subsequent AJAX requests on the page to have their COOKIEs set, this can be achieved by simply using WKUserScript to set the values programmatically via Javascript at document start like so:

如果需要对页面上的后续AJAX请求设置COOKIE,可以通过简单地使用WKUserScript在document start时通过Javascript以编程方式设置值,如:

WKUserContentController* userCOntentController= WKUserContentController.new;
WKUserScript * COOKIEScript = [[WKUserScript alloc] 
    initWithSource: @"document.COOKIE = 'TeskCOOKIEKey1=TeskCOOKIEValue1';document.COOKIE = 'TeskCOOKIEKey2=TeskCOOKIEValue2';"
    injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
// again, use stringWithFormat: in the above line to inject your values programmatically
[userContentController addUserScript:COOKIEScript];
WKWebViewConfiguration* webViewCOnfig= WKWebViewConfiguration.new;
webViewConfig.userCOntentController= userContentController;
WKWebView * webView = [[WKWebView alloc] initWithFrame:CGRectMake(/*set your values*/) configuration:webViewConfig];

Combining these two techniques should give you enough tools to transfer COOKIE values from Native App Land to Web View Land. You can find more info on the COOKIE Javascript api on mozilla's page, if you require some more advanced COOKIEs.

结合这两种技术,您将有足够的工具将COOKIE值从本地应用程序域传输到Web视图域。如果您需要一些更高级的COOKIE,您可以在mozilla页面上找到关于COOKIE Javascript api的更多信息。

Yeah it sucks that Apple is not supporting many of the niceties of UIWebView. Not sure if they will ever support them, but hopefully they will get on this soon. Hope this helps!

是的,苹果没有支持UIWebView的很多优点,这太糟糕了。不确定他们是否会支持他们,但希望他们很快就能做到。希望这可以帮助!

#2


53  

After playing with this answer (which was fantastically helpful :) we've had to make a few changes:

在尝试了这个答案(非常有用)之后,我们必须做一些改变:

  • We need the web views to deal with multiple domains without leaking private COOKIE information between those domains
  • 我们需要web视图来处理多个域,而不泄漏这些域之间的私有COOKIE信息
  • We need it to honour secure COOKIEs
  • 我们需要它来保护安全的饼干
  • If the server changes a COOKIE value we want our app to know about it in NSHTTPCOOKIEStorage
  • 如果服务器改变了一个COOKIE值,我们希望我们的应用程序在NSHTTPCOOKIEStorage中知道它
  • If the server changes a COOKIE value we don't want our scripts to reset it back to it's original value when you follow a link / AJAX etc.
  • 如果服务器更改了一个COOKIE值,我们不希望我们的脚本在您遵循链接/ AJAX等时将其重置为原始值。

So we modified our code to be this;

我们把代码修改成这样;

Creating a request

NSMutableURLRequest *request = [originalRequest mutableCopy];
NSString *validDomain = request.URL.host;
const BOOL requestIsSecure = [request.URL.scheme isEqualToString:@"https"];

NSMutableArray *array = [NSMutableArray array];
for (NSHTTPCOOKIE *COOKIE in [[NSHTTPCOOKIEStorage sharedHTTPCOOKIEStorage] COOKIEs]) {
    // Don't even bother with values containing a `'`
    if ([COOKIE.name rangeOfString:@"'"].location != NSNotFound) {
        NSLog(@"Skipping %@ because it contains a '", COOKIE.properties);
        continue;
    }

    // Is the COOKIE for current domain?
    if (![COOKIE.domain hasSuffix:validDomain]) {
        NSLog(@"Skipping %@ (because not %@)", COOKIE.properties, validDomain);
        continue;
    }

    // Are we secure only?
    if (COOKIE.secure && !requestIsSecure) {
        NSLog(@"Skipping %@ (because %@ not secure)", COOKIE.properties, request.URL.absoluteString);
        continue;
    }

    NSString *value = [NSString stringWithFormat:@"%@=%@", COOKIE.name, COOKIE.value];
    [array addObject:value];
}

NSString *header = [array componentsJoinedByString:@";"];
[request setValue:header forHTTPHeaderField:@"COOKIE"];

// Now perform the request...

This makes sure that the first request has the correct COOKIEs set, without sending any COOKIEs from the shared storage that are for other domains, and without sending any secure COOKIEs into an insecure request.

这样可以确保第一个请求设置了正确的COOKIE,而不会从共享存储中发送任何其他域的COOKIE,也不会向不安全请求发送任何安全COOKIE。

Dealing with further requests

We also need to make sure that other requests have the COOKIEs set. This is done using a script that runs on document load which checks to see if there is a COOKIE set and if not, set it to the value in NSHTTPCOOKIEStorage.

我们还需要确保其他请求具有COOKIE集。

// Get the currently set COOKIE names in Javascriptland
[script appendString:@"var COOKIENames = document.COOKIE.split('; ').map(function(COOKIE) { return COOKIE.split('=')[0] } );\n"];

for (NSHTTPCOOKIE *COOKIE in [[NSHTTPCOOKIEStorage sharedHTTPCOOKIEStorage] COOKIEs]) {
    // Skip COOKIEs that will break our script
    if ([COOKIE.value rangeOfString:@"'"].location != NSNotFound) {
        continue;
    }

    // Create a line that appends this COOKIE to the web view's document's COOKIEs
    [script appendFormat:@"if (COOKIENames.indexOf('%@') == -1) { document.COOKIE='%@'; };\n", COOKIE.name, COOKIE.wn_JavascriptString];
}

WKUserContentController *userCOntentController= [[WKUserContentController alloc] init];
WKUserScript *COOKIEInScript = [[WKUserScript alloc] initWithSource:script
                                                      injectionTime:WKUserScriptInjectionTimeAtDocumentStart
                                                   forMainFrameOnly:NO];
[userContentController addUserScript:COOKIEInScript];

...

// Create a config out of that userContentController and specify it when we create our web view.
WKWebViewConfiguration *cOnfig= [[WKWebViewConfiguration alloc] init];
config.userCOntentController= userContentController;

self.webView = [[WKWebView alloc] initWithFrame:webView.bounds configuration:config];

Dealing with COOKIE changes

We also need to deal with the server changing a COOKIE's value. This means adding another script to call back out of the web view we are creating to update our NSHTTPCOOKIEStorage.

我们还需要处理服务器更改COOKIE值的问题。这意味着添加另一个脚本,以从我们正在创建的web view中调用,以更新我们的NSHTTPCOOKIEStorage。

WKUserScript *COOKIEOutScript = [[WKUserScript alloc] initWithSource:@"window.webkit.messageHandlers.updateCOOKIEs.postMessage(document.COOKIE);"
                                                       injectionTime:WKUserScriptInjectionTimeAtDocumentStart
                                                    forMainFrameOnly:NO];
[userContentController addUserScript:COOKIEOutScript];

[userContentController addScriptMessageHandler:webView
                                          name:@"updateCOOKIEs"];

and implementing the delegate method to update any COOKIEs that have changed, making sure that we are only updating COOKIEs from the current domain!

并实现委托方法来更新任何已更改的COOKIE,确保我们只更新来自当前域的COOKIE !

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    NSArray *COOKIEs = [message.body componentsSeparatedByString:@"; "];
    for (NSString *COOKIE in COOKIEs) {
        // Get this COOKIE's name and value
        NSArray *comps = [COOKIE componentsSeparatedByString:@"="];
        if (comps.count <2) {
            continue;
        }

        // Get the COOKIE in shared storage with that name
        NSHTTPCOOKIE *localCOOKIE = nil;
        for (NSHTTPCOOKIE *c in [[NSHTTPCOOKIEStorage sharedHTTPCOOKIEStorage] COOKIEsForURL:self.wk_webView.URL]) {
            if ([c.name isEqualToString:comps[0]]) {
                localCOOKIE = c;
                break;
            }
        }

        // If there is a COOKIE with a stale value, update it now.
        if (localCOOKIE) {
            NSMutableDictionary *props = [localCOOKIE.properties mutableCopy];
            props[NSHTTPCOOKIEValue] = comps[1];
            NSHTTPCOOKIE *updatedCOOKIE = [NSHTTPCOOKIE COOKIEWithProperties:props];
            [[NSHTTPCOOKIEStorage sharedHTTPCOOKIEStorage] setCOOKIE:updatedCOOKIE];
        }
    }
}

This seems to fix our COOKIE problems without us having to deal with each place we use WKWebView differently. We can now just use this code as a helper to create our webviews and it transparently updates NSHTTPCOOKIEStorage for us.

这似乎可以解决我们的COOKIE问题,而不必处理我们使用WKWebView的每个地方。我们现在可以使用这个代码作为一个助手来创建我们的webview,它会透明地为我们更新NSHTTPCOOKIEStorage。


EDIT: Turns out I used a private category on NSHTTPCOOKIE - here's the code:

编辑:原来我在NSHTTPCOOKIE上使用了一个私有类别——下面是代码:

- (NSString *)wn_JavascriptString {
    NSString *string = [NSString stringWithFormat:@"%@=%@;domain=%@;path=%@",
                        self.name,
                        self.value,
                        self.domain,
                        self.path ?: @"/"];

    if (self.secure) {
        string = [string stringByAppendingString:@";secure=true"];
    }

    return string;
}

#3


19  

work for me

为我工作

func webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) {
    let headerFields = navigationAction.request.allHTTPHeaderFields
    var headerIsPresent = contains(headerFields?.keys.array as! [String], "COOKIE")

    if headerIsPresent {
        decisionHandler(WKNavigationActionPolicy.Allow)
    } else {
        let req = NSMutableURLRequest(URL: navigationAction.request.URL!)
        let COOKIEs = yourCOOKIEData
        let values = NSHTTPCOOKIE.requestHeaderFieldsWithCOOKIEs(COOKIEs)
        req.allHTTPHeaderFields = values
        webView.loadRequest(req)

        decisionHandler(WKNavigationActionPolicy.Cancel)
    }
}

#4


13  

Here is my version of Mattrs solution in Swift for injecting all COOKIEs from HTTPCOOKIEStorage. This was done mainly to inject an authentication COOKIE to create a user session.

这是我在Swift中的Mattrs解决方案版本,用于从HTTPCOOKIEStorage注入所有COOKIE。这主要是为了注入一个身份验证COOKIE来创建一个用户会话。

public func setupWebView() {
    let userCOntentController= WKUserContentController()
    if let COOKIEs = HTTPCOOKIEStorage.shared.COOKIEs {
        let script = getJSCOOKIEsString(for: COOKIEs)
        let COOKIEScript = WKUserScript(source: script, injectionTime: .atDocumentStart, forMainFrameOnly: false)
        userContentController.addUserScript(COOKIEScript)
    }
    let webViewCOnfig= WKWebViewConfiguration()
    webViewConfig.userCOntentController= userContentController

    self.webView = WKWebView(frame: self.webViewContainer.bounds, configuration: webViewConfig)
}

///Generates script to create given COOKIEs
public func getJSCOOKIEsString(for COOKIEs: [HTTPCOOKIE]) -> String {
    var result = ""
    let dateFormatter = DateFormatter()
    dateFormatter.timeZOne= TimeZone(abbreviation: "UTC")
    dateFormatter.dateFormat = "EEE, d MMM yyyy HH:mm:ss zzz"

    for COOKIE in COOKIEs {
        result += "document.COOKIE='\(COOKIE.name)=\(COOKIE.value); domain=\(COOKIE.domain); path=\(COOKIE.path); "
        if let date = COOKIE.expiresDate {
            result += "expires=\(dateFormatter.stringFromDate(date)); "
        }
        if (COOKIE.secure) {
            result += "secure; "
        }
        result += "'; "
    }
    return result
}

#5


8  

Swift 3 update :

斯威夫特3更新:

func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
    if let urlRespOnse= navigationResponse.response as? HTTPURLResponse,
       let url = urlResponse.url,
       let allHeaderFields = urlResponse.allHeaderFields as? [String : String] {
       let COOKIEs = HTTPCOOKIE.COOKIEs(withResponseHeaderFields: allHeaderFields, for: url)
       HTTPCOOKIEStorage.shared.setCOOKIEs(COOKIEs , for: urlResponse.url!, mainDocumentURL: nil)
       decisionHandler(.allow)
    }
}

#6


7  

set COOKIE

集饼干

self.webView.evaluateJavascript("document.COOKIE='access_token=your token';domain='your domain';") { (data, error) -> Void in
        self.webView.reload()
}

delete COOKIE

删除饼干

self.webView.evaluateJavascript("document.COOKIE='access_token=';domain='your domain';") { (data, error) -> Void in
        self.webView.reload()
}

#7


6  

In iOS 11, you can manage COOKIE now :), see this session: https://developer.apple.com/videos/play/wwdc2017/220/

在ios11中,您现在可以管理COOKIE:),请参见这个会话:https://developer.apple.com/videos/play/wwdc2017/220/

enter image description here

#8


6  

The COOKIEs must be set on the configuration before the WKWebView is created. Otherwise, even with WKHTTPCOOKIEStore's setCOOKIE completion handler, the COOKIEs won't reliably be synced to the web view. This goes back to this line from the docs on WKWebViewConfiguration

在创建WKWebView之前,必须在配置上设置COOKIE。否则,即使使用WKHTTPCOOKIEStore的setCOOKIE完成处理程序,COOKIE也不能可靠地同步到web视图。这可以追溯到WKWebViewConfiguration上的文档

@NSCopying var configuration: WKWebViewConfiguration { get }

That @NSCopying is somewhat of a deep copy. The implementation is beyond me, but the end result is that unless you set COOKIEs before initializing the webview, you can't count on the COOKIEs being there. This can complicate app architecture because not initializing a view becomes an asynchronous process. You'll end up with something like this

@NSCopying有点像一个深层拷贝。实现超出了我的范围,但是最终的结果是,除非在初始化webview之前设置COOKIE,否则不能指望COOKIE在那里。这可能会使应用程序架构复杂化,因为不初始化视图就会变成一个异步过程。你会得到这样的结果

extension WKWebViewConfiguration {
    /// Async Factory method to acquire WKWebViewConfigurations packaged with system COOKIEs
    static func COOKIEsIncluded(completion: @escaping (WKWebViewConfiguration?) -> Void) {
        let cOnfig= WKWebViewConfiguration()
        guard let COOKIEs = HTTPCOOKIEStorage.shared.COOKIEs else {
            completion(config)
            return
        }
        // Use nonPersistent() or default() depending on if you want COOKIEs persisted to disk
        // and shared between WKWebViews of the same app (default), or not persisted and not shared
        // across WKWebViews in the same app.
        let dataStore = WKWebsiteDataStore.nonPersistent()
        let waitGroup = DispatchGroup()
        for COOKIE in COOKIEs {
            waitGroup.enter()
            dataStore.httpCOOKIEStore.setCOOKIE(COOKIE) { waitGroup.leave() }
        }
        waitGroup.notify(queue: DispatchQueue.main) {
            config.websiteDataStore = dataStore
            completion(config)
        }
    }
}

and then to use it something like

然后使用它

override func loadView() {
    view = UIView()
    WKWebViewConfiguration.COOKIEsIncluded { [weak self] config in
        let webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.load(request)
        self.view = webView
    }
}

The above example defers view creation until the last possible moment, another solution would be to create the config or webview well in advance and handle the asynchronous nature before creation of a view controller.

上面的示例将视图创建延迟到可能的最后一刻,另一种解决方案是提前创建配置或webview,并在创建视图控制器之前处理异步特性。

A final note: once you create this webview, you have set it loose into the wild, you can't add more COOKIEs without using methods described in this answer. You can however use the WKHTTPCOOKIEStoreObserver api to at least observe changes happening to COOKIEs. So if a session COOKIE gets updated in the webview, you can manually update the system's HTTPCOOKIEStorage with this new COOKIE if desired.

最后一个注意事项:一旦你创建了这个webview,你将它释放到野外,你不能添加更多的COOKIE而不使用这个答案中描述的方法。但是,您可以使用WKHTTPCOOKIEStoreObserver api至少观察到COOKIE发生的变化。因此,如果一个会话COOKIE在webview中被更新,你可以用这个新COOKIE手动更新系统的HTTPCOOKIEStorage。

For more on this, skip to 18:00 at this 2017 WWDC Session Custom Web Content Loading. At the beginning of this session, there is a deceptive code sample which omits the fact that the webview should be created in the completion handler.

关于这方面的更多信息,请跳转到2017年WWDC自定义Web内容加载的18:00。在这个会话的开始,有一个欺骗性的代码示例,它忽略了应该在完成处理程序中创建webview的事实。

COOKIEStore.setCOOKIE(COOKIE!) {
    webView.load(loggedInURLRequest)
}

The live demo at 18:00 clarifies this.

18:00现场演示澄清了这一点。

#9


2  

Please find the solution which most likely will work for you out of the box. Basically it's modified and updated for Swift 4 @user3589213's answer.

请找出最适合你的解决方案。基本上,它对Swift 4 @user3589213的答案进行了修改和更新。

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    let headerKeys = navigationAction.request.allHTTPHeaderFields?.keys
    let hasCOOKIEs = headerKeys?.contains("COOKIE") ?? false

    if hasCOOKIEs {
        decisionHandler(.allow)
    } else {
        let COOKIEs = HTTPCOOKIE.requestHeaderFields(with: HTTPCOOKIEStorage.shared.COOKIEs ?? [])

        var headers = navigationAction.request.allHTTPHeaderFields ?? [:]
        headers += COOKIEs

        var req = navigationAction.request
        req.allHTTPHeaderFields = headers

        webView.load(req)

        decisionHandler(.cancel)
    }
}

#10


1  

The better fix for XHR requests is shown here

这里显示了对XHR请求的更好修复

Swift 4 version:

斯威夫特4版本:

func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Swift.Void) {
    guard
        let respOnse= navigationResponse.response as? HTTPURLResponse,
        let url = navigationResponse.response.url
    else {
        decisionHandler(.cancel)
        return
    }

    if let headerFields = response.allHeaderFields as? [String: String] {
        let COOKIEs = HTTPCOOKIE.COOKIEs(withResponseHeaderFields: headerFields, for: url)
        COOKIEs.forEach { (COOKIE) in
            HTTPCOOKIEStorage.shared.setCOOKIE(COOKIE)
        }
    }

    decisionHandler(.allow)
}

#11


0  

After looking through various answers here and not having any success, I combed through the WebKit documentation and stumbled upon the requestHeaderFields static method on HTTPCOOKIE, which converts an array of COOKIEs into a format suitable for a header field. Combining this with mattr's insight of updating the URLRequest before loading it with the COOKIE headers got me through the finish line.

在查看了各种各样的答案并没有取得任何成功之后,我梳理了WebKit文档,并在HTTPCOOKIE上发现了requestHeaderFields静态方法,该方法将一组COOKIE转换为适合头字段的格式。结合mattr在使用COOKIE头部加载URLRequest之前更新URLRequest的见解,我完成了这一任务。

Swift 4.1:

var request = URLRequest(url: URL(string: "https://example.com/")!)
let headers = HTTPCOOKIE.requestHeaderFields(with: COOKIEs)
for (name, value) in headers {
    request.addValue(value, forHTTPHeaderField: name)
}

let webView = WKWebView(frame: self.view.frame)
webView.load(request)

To make this even simpler, use an extension:

为了使这更简单,使用扩展:

extension WKWebView {
    func load(_ request: URLRequest, with COOKIEs: [HTTPCOOKIE]) {
        var request = request
        let headers = HTTPCOOKIE.requestHeaderFields(with: COOKIEs)
        for (name, value) in headers {
            request.addValue(value, forHTTPHeaderField: name)
        }

        load(request)
    }
}

Now it just becomes:

现在就变成了:

let request = URLRequest(url: URL(string: "https://example.com/")!)
let webView = WKWebView(frame: self.view.frame)
webView.load(request, with: COOKIEs)

This extension is also available in LionheartExtensions if you just want a drop-in solution. Cheers!

如果您只是想要一个drop-in解决方案,那么在lionheartexties中也可以使用这个扩展。干杯!


推荐阅读
  • 本文详细探讨了在微服务架构中,使用Feign进行远程调用时出现的请求头丢失问题,并提供了具体的解决方案。重点讨论了单线程和异步调用两种场景下的处理方法。 ... [详细]
  • CentOS 7.6环境下Prometheus与Grafana的集成部署指南
    本文旨在提供一套详细的步骤,指导读者如何在CentOS 7.6操作系统上成功安装和配置Prometheus 2.17.1及Grafana 6.7.2-1,实现高效的数据监控与可视化。 ... [详细]
  • ssm框架整合及工程分层1.先创建一个新的project1.1配置pom.xml ... [详细]
  • Spring Security核心概念与应用实践
    本文详细介绍了Spring Security的核心机制,包括其作为一系列过滤器的工作原理,如何实现用户认证与授权,以及常见的配置方法和高级特性如CSRF防护。 ... [详细]
  • 前言Git是目前最流行的版本控制系统,在它的基础之上,GitHub和GitLab成为当前最流行的代码托管平台,它们均提供的代码评审、项目管理、持续集成等功能,越来越多的互联网企业都 ... [详细]
  • Redux入门指南
    本文介绍Redux的基本概念和工作原理,帮助初学者理解如何使用Redux管理应用程序的状态。Redux是一个用于JavaScript应用的状态管理库,特别适用于React项目。 ... [详细]
  • 微信小程序:授权登录与手机号绑定
    本文详细介绍了微信小程序中用户授权登录及绑定手机号的流程,结合官方指引和实际开发经验,提供了一套完整的实现方案,帮助开发者更好地理解和应用。 ... [详细]
  • 本文探讨了在 SQL Server 中使用 JDBC 插入数据时遇到的问题。通过详细分析代码和数据库配置,提供了解决方案并解释了潜在的原因。 ... [详细]
  • CentOS 6.8 上安装 Oracle 10.2.0.1 的常见问题及解决方案
    本文记录了在 CentOS 6.8 系统上安装 Oracle 10.2.0.1 数据库时遇到的问题及解决方法,包括依赖库缺失、操作系统版本不兼容、用户权限不足等问题。 ... [详细]
  • Django Token 认证详解与 HTTP 401、403 状态码的区别
    本文详细介绍了如何在 Django 中配置和使用 Token 认证,并解释了 HTTP 401 和 HTTP 403 状态码的区别。通过具体的代码示例,帮助开发者理解认证机制及权限控制。 ... [详细]
  • 深入解析:OpenShift Origin环境下的Kubernetes Spark Operator
    本文探讨了如何在OpenShift Origin平台上利用Kubernetes Spark Operator来管理和部署Apache Spark集群与应用。作为Radanalytics.io项目的一部分,这一开源工具为大数据处理提供了强大的支持。 ... [详细]
  • 本文详细介绍了JSP(Java Server Pages)的九大内置对象及其功能,探讨了JSP与Servlet之间的关系及差异,并提供了实际编码示例。此外,还讨论了网页开发中常见的编码转换问题以及JSP的两种页面跳转方式。 ... [详细]
  • 本文探讨了一个特定于 Spring 4.2.5 的问题,即在应用上下文刷新事件(ContextRefreshedEvent)触发时,带有 @Transactional 注解的 Bean 未能正确代理事务。该问题在 Spring 4.1.9 版本中正常运行,但在升级至 4.2.5 后出现异常。 ... [详细]
  • 本文将指导如何在JFinal框架中快速搭建一个简易的登录系统,包括环境配置、数据库设计、项目结构规划及核心代码实现等环节。 ... [详细]
  • 本文档详细介绍了思科交换机的基本配置命令,包括进入特权模式、配置交换机名称及密码、VLAN配置、端口访问、查看配置信息、恢复出厂设置以及远程登录设置等。 ... [详细]
author-avatar
秦延深_791
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有