Objective-C 中的 URL 减去查询字符串

发布于 2024-10-04 10:59:12 字数 284 浏览 4 评论 0原文

在 Objective-C 中获取 url 减去其查询字符串的最佳方法是什么?一个例子:

输入:

http://www.example.com/folder/page.htm?param1=value1&param2=value2

输出:

http://www.example.com/folder/page.htm

是否有一个我缺少的 NSURL 方法来执行此操作?

What's the best way to get an url minus its query string in Objective-C? An example:

Input:

http://www.example.com/folder/page.htm?param1=value1¶m2=value2

Output:

http://www.example.com/folder/page.htm

Is there a NSURL method to do this that I'm missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

感受沵的脚步 2024-10-11 10:59:12

从 iOS 8/OS X 10.9 开始,有一种更简单的方法可以使用 NSURLComponents 来完成此操作。

NSURL *url = [NSURL URLWithString:@"http://hostname.com/path?key=value"];
NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithURL:url resolvingAgainstBaseURL:NO];

urlComponents.query = nil; // Strip out query parameters.
NSLog(@"Result: %@", urlComponents.string); // Should print http://hostname.com/path

Since iOS 8/OS X 10.9, there is an easier way to do this with NSURLComponents.

NSURL *url = [NSURL URLWithString:@"http://hostname.com/path?key=value"];
NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithURL:url resolvingAgainstBaseURL:NO];

urlComponents.query = nil; // Strip out query parameters.
NSLog(@"Result: %@", urlComponents.string); // Should print http://hostname.com/path
城歌 2024-10-11 10:59:12

我看不到 NSURL 方法。您可以尝试以下操作:

NSURL *newURL = [[NSURL alloc] initWithScheme:[url scheme]
                                         host:[url host]
                                         path:[url path]];

测试看起来不错:

#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
    NSAutoreleasePool *arp = [[NSAutoreleasePool alloc] init];

    NSURL *url = [NSURL URLWithString:@"http://www.abc.com/foo/bar.cgi?a=1&b=2"];
    NSURL *newURL = [[[NSURL alloc] initWithScheme:[url scheme]
                                              host:[url host]
                                              path:[url path]] autorelease];
    NSLog(@"\n%@ --> %@", url, newURL);
    [arp release];
    return 0;
}

运行此命令会产生:

$ gcc -lobjc -framework Foundation -std=c99 test.m ; ./a.out 
2010-11-25 09:20:32.189 a.out[36068:903] 
http://www.abc.com/foo/bar.cgi?a=1&b=2 --> http://www.abc.com/foo/bar.cgi

There's no NSURL method I can see. You might try something like:

NSURL *newURL = [[NSURL alloc] initWithScheme:[url scheme]
                                         host:[url host]
                                         path:[url path]];

Testing looks good:

#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
    NSAutoreleasePool *arp = [[NSAutoreleasePool alloc] init];

    NSURL *url = [NSURL URLWithString:@"http://www.abc.com/foo/bar.cgi?a=1&b=2"];
    NSURL *newURL = [[[NSURL alloc] initWithScheme:[url scheme]
                                              host:[url host]
                                              path:[url path]] autorelease];
    NSLog(@"\n%@ --> %@", url, newURL);
    [arp release];
    return 0;
}

Running this produces:

$ gcc -lobjc -framework Foundation -std=c99 test.m ; ./a.out 
2010-11-25 09:20:32.189 a.out[36068:903] 
http://www.abc.com/foo/bar.cgi?a=1&b=2 --> http://www.abc.com/foo/bar.cgi
梦罢 2024-10-11 10:59:12

这是 Andree 的答案 的 Swift 版本,带有一些额外的风味 -

extension NSURL {

    func absoluteStringByTrimmingQuery() -> String? {
        if var urlcomponents = NSURLComponents(URL: self, resolvingAgainstBaseURL: false) {
            urlcomponents.query = nil
            return urlcomponents.string
        }
        return nil
    }
}

你可以这样称呼它 -

let urlMinusQueryString  = url.absoluteStringByTrimmingQuery()

Here is the Swift version of Andree's answer, with some extra flavour -

extension NSURL {

    func absoluteStringByTrimmingQuery() -> String? {
        if var urlcomponents = NSURLComponents(URL: self, resolvingAgainstBaseURL: false) {
            urlcomponents.query = nil
            return urlcomponents.string
        }
        return nil
    }
}

You can call it like -

let urlMinusQueryString  = url.absoluteStringByTrimmingQuery()
天涯沦落人 2024-10-11 10:59:12

Swift 版本

extension URL {
    func absoluteStringByTrimmingQuery() -> String? {
        if var urlcomponents = URLComponents(url: self, resolvingAgainstBaseURL: false) {
            urlcomponents.query = nil
            return urlcomponents.string
        }
        return nil
    }
}

希望这有帮助!

Swift Version

extension URL {
    func absoluteStringByTrimmingQuery() -> String? {
        if var urlcomponents = URLComponents(url: self, resolvingAgainstBaseURL: false) {
            urlcomponents.query = nil
            return urlcomponents.string
        }
        return nil
    }
}

Hope this helps!

心凉 2024-10-11 10:59:12

您可能需要的是 url 的主机和路径组件的组合:

NSString *result = [[url host] stringByAppendingPathComponent:[url path]];

What you probably need is a combination of url's host and path components:

NSString *result = [[url host] stringByAppendingPathComponent:[url path]];
当梦初醒 2024-10-11 10:59:12

您可以尝试使用 NSURLquery 来获取参数,然后使用 NSStringstringByReplacingOccurrencesOfString 删除该值?

NSURL *before = [NSURL URLWithString:@"http://www.example.com/folder/page.htm?param1=value1¶m2=value2"];
NSString *after = [before.absoluteString stringByReplacingOccurrencesOfString:before.query withString:@""];

请注意,最终 URL 仍将以 ? 结尾,但如果需要,您也可以轻松删除它。

You could try using query of NSURL to get the parameters, then strip that value using stringByReplacingOccurrencesOfString of NSString?

NSURL *before = [NSURL URLWithString:@"http://www.example.com/folder/page.htm?param1=value1¶m2=value2"];
NSString *after = [before.absoluteString stringByReplacingOccurrencesOfString:before.query withString:@""];

Note, the final URL will still end with ?, but you could easily strip that as well if needed.

清风无影 2024-10-11 10:59:12

我认为 -baseURL 可能会做你想要的。

如果没有,您可以通过 NSString 进行往返,如下所示:

NSString *string = [myURL absoluteString];
NSString base = [[string componentsSeparatedByString:@"?"] objectAtIndex:0];
NSURL *trimmed = [NSURL URLWithString:base];

I think -baseURL might do what you want.

If not, you can can do a round trip through NSString like so:

NSString *string = [myURL absoluteString];
NSString base = [[string componentsSeparatedByString:@"?"] objectAtIndex:0];
NSURL *trimmed = [NSURL URLWithString:base];
半山落雨半山空 2024-10-11 10:59:12

NSURL 有一个 query 属性,其中包含 GET url 中 ? 之后的所有内容。因此,只需从absoluteString 的末尾减去它,您就得到了没有查询的url。

NSURL *originalURL = [NSURL URLWithString:@"https://[email protected]:1000/file/path/?q=dogfood"];
NSString *strippedString = [originalURL absoluteString];
NSUInteger queryLength = [[originalURL query] length];
strippedString = (queryLength ? [strippedString substringToIndex:[strippedString length] - (queryLength + 1)] : strippedString);
NSLog(@"Output: %@", strippedString);

日志:

Output: https://[email protected]:1000/file/path/

+1 用于 ?,它不是查询的一部分。

NSURL has a query property which contains everything after the ? in a GET url. So simply subtract that from the end of the absoluteString, and you've got the url without the query.

NSURL *originalURL = [NSURL URLWithString:@"https://[email protected]:1000/file/path/?q=dogfood"];
NSString *strippedString = [originalURL absoluteString];
NSUInteger queryLength = [[originalURL query] length];
strippedString = (queryLength ? [strippedString substringToIndex:[strippedString length] - (queryLength + 1)] : strippedString);
NSLog(@"Output: %@", strippedString);

Logs:

Output: https://[email protected]:1000/file/path/

The +1 is for the ? which is not part of query.

想念有你 2024-10-11 10:59:12

您可能会喜欢 NSMutableString 类的 replaceOccurrencesOfString:withString:options:range: 方法。我通过编写 类别 for NSURL

#import <Foundation/Foundation.h>

@interface NSURL (StripQuery)
// Returns a new URL with the query stripped out.
// Note: If there is no query, returns a copy of this URL.
- (NSURL *)URLByStrippingQuery;
@end

@implementation NSURL (StripQuery)
- (NSURL *)URLByStrippingQuery
{
    NSString *query = [self query];
    // Simply copy if there was no query. (query is nil if URL has no '?',
    // and equal to @"" if it has a '?' but no query after.)
    if (!query || ![query length]) {
        return [self copy];
    }
    NSMutableString *urlString = [NSMutableString stringWithString:[self absoluteString]];
    [urlString replaceOccurrencesOfString:query
                               withString:@""
                                  options:NSBackwardsSearch
                                    range:NSMakeRange(0, [urlString length])];
    return [NSURL URLWithString:urlString];
}
@end

这样,我可以将此消息发送到现有的 NSURL 对象,并让一个新的 NSURL 对象返回给我。

我使用以下代码对其进行了测试:

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        NSURL *url = [NSURL URLWithString:@"http://www.example.com/script.php?key1=val1&key2=val2"];
//      NSURL *url = [NSURL URLWithString:@"http://www.example.com/script.php?"];
//      NSURL *url = [NSURL URLWithString:@"http://www.example.com/script.php"];
        NSURL *newURL = [url URLByStrippingQuery];
        NSLog(@"Original URL: \"%@\"\n", [url absoluteString]);
        NSLog(@"Stripped URL: \"%@\"\n", [newURL absoluteString]);
    }
    return 0;
}

我得到了以下输出(减去时间戳):

Original URL: "http://www.example.com/script.php?key1=val1&key2=val2"
Stripped URL: "http://www.example.com/script.php?"

请注意,问号(“?”)仍然存在。我将把它留给读者以安全的方式删除它。

You might fancy the method replaceOccurrencesOfString:withString:options:range: of the NSMutableString class. I solved this by writing a category for NSURL:

#import <Foundation/Foundation.h>

@interface NSURL (StripQuery)
// Returns a new URL with the query stripped out.
// Note: If there is no query, returns a copy of this URL.
- (NSURL *)URLByStrippingQuery;
@end

@implementation NSURL (StripQuery)
- (NSURL *)URLByStrippingQuery
{
    NSString *query = [self query];
    // Simply copy if there was no query. (query is nil if URL has no '?',
    // and equal to @"" if it has a '?' but no query after.)
    if (!query || ![query length]) {
        return [self copy];
    }
    NSMutableString *urlString = [NSMutableString stringWithString:[self absoluteString]];
    [urlString replaceOccurrencesOfString:query
                               withString:@""
                                  options:NSBackwardsSearch
                                    range:NSMakeRange(0, [urlString length])];
    return [NSURL URLWithString:urlString];
}
@end

This way, I can send this message to existing NSURL objects and have a new NSURL object be returned to me.

I tested it using this code:

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        NSURL *url = [NSURL URLWithString:@"http://www.example.com/script.php?key1=val1&key2=val2"];
//      NSURL *url = [NSURL URLWithString:@"http://www.example.com/script.php?"];
//      NSURL *url = [NSURL URLWithString:@"http://www.example.com/script.php"];
        NSURL *newURL = [url URLByStrippingQuery];
        NSLog(@"Original URL: \"%@\"\n", [url absoluteString]);
        NSLog(@"Stripped URL: \"%@\"\n", [newURL absoluteString]);
    }
    return 0;
}

and I got the following output (minus the time stamps):

Original URL: "http://www.example.com/script.php?key1=val1&key2=val2"
Stripped URL: "http://www.example.com/script.php?"

Note that the question mark ('?') still remains. I will leave it up to the reader to remove it in a secure way.

墨洒年华 2024-10-11 10:59:12

我们应该尝试使用 NSURLComponents

  NSURL *url = @"http://example.com/test";
  NSURLComponents *comps = [[NSURLComponents alloc] initWithURL:url resolvingAgainstBaseURL:YES];
  NSString *cleanUrl = [NSString stringWithFormat:@"%@://%@",comps.scheme,comps.host];
  if(comps.path.length > 0){
     cleanUrl = [NSString stringWithFormat:@"%@/%@",cleanUrl,comps.path];
  }

We should try to use NSURLComponents

  NSURL *url = @"http://example.com/test";
  NSURLComponents *comps = [[NSURLComponents alloc] initWithURL:url resolvingAgainstBaseURL:YES];
  NSString *cleanUrl = [NSString stringWithFormat:@"%@://%@",comps.scheme,comps.host];
  if(comps.path.length > 0){
     cleanUrl = [NSString stringWithFormat:@"%@/%@",cleanUrl,comps.path];
  }
巾帼英雄 2024-10-11 10:59:12

我认为您正在寻找的是 baseUrl

I think what you're looking for is baseUrl.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文