iOS網(wǎng)絡(luò)編程

一培廓、URL

  • URL的全稱是Uniform Resource Locator(統(tǒng)一資源定位符),通過(guò)1個(gè)URL拷恨,能找到互聯(lián)網(wǎng)上唯一的1個(gè)資源,URL就是資源的地址、位置,互聯(lián)網(wǎng)上的每個(gè)資源都有一個(gè)唯一的URL

  • 的基本格式 = 協(xié)議://主機(jī)地址/路徑,示例:
    http://www.baidu.com/img/logo.png
    http://111.111.111.111/img/bdlogo.gif

  • 協(xié)議坡氯、主機(jī)地址、路徑的含義:
    協(xié)議:不同的協(xié)議都哭,代表著不同的資源查找方式详民、資源傳輸方式
    主機(jī)地址:存放資源的主機(jī)(服務(wù)器)的IP地址(域名)
    路徑:資源在主機(jī)(服務(wù)器)中的具體位置

二、HTTP協(xié)議

1.HTTP協(xié)議簡(jiǎn)介
  • HTTP的全稱是Hypertext Transfer Protocol帚呼,超文本傳輸協(xié)議
  • 規(guī)定客戶端和服務(wù)器之間的數(shù)據(jù)傳輸格式
  • 讓客戶端和服務(wù)器能有效地進(jìn)行數(shù)據(jù)溝通
2.HTTP協(xié)議特點(diǎn)
  • 簡(jiǎn)單快速:因?yàn)镠TTP協(xié)議簡(jiǎn)單掏缎,所以HTTP服務(wù)器的程序規(guī)模小,因而通信速度很快
  • 靈活:HTTP允許傳輸各種各樣的數(shù)據(jù)
  • HTTP 0.9和1.0使用非持續(xù)連接:限制每次連接只處理一個(gè)請(qǐng)求煤杀,服務(wù)器對(duì)客戶端的請(qǐng)求做出響應(yīng)后眷蜈,馬上斷開(kāi)連接,這種方式可以節(jié)省傳輸時(shí)間
3.HTTP協(xié)議的請(qǐng)求方法
  • 在HTTP/1.1協(xié)議中沈自,定義了8種發(fā)送http請(qǐng)求的方法:GET酌儒、POST、OPTIONS枯途、HEAD忌怎、PUT籍滴、DELETE、TRACE榴啸、CONNECT孽惰、PATCH
  • PUT :增、DELETE :刪鸥印、POST:改勋功、GET:查
  • 最常用的是GET和POST(實(shí)際上GET和POST都能辦到增刪改查)
4.GET和POST
4.1、GET
  • 在請(qǐng)求URL后面以?的形式跟上發(fā)給服務(wù)器的參數(shù)库说,多個(gè)參數(shù)之間用&隔開(kāi)狂鞋,比如:http://ww.test.com/login?username=123&pwd=234&type=JSON
  • 由于瀏覽器和服務(wù)器對(duì)URL長(zhǎng)度有限制,因此在URL后面附帶的參數(shù)是有限制的潜的,通常不能超過(guò)1KB
  • 如果僅僅是索取數(shù)據(jù)(數(shù)據(jù)查詢)骚揍,建議使用GET
4.2、POST
  • 發(fā)給服務(wù)器的參數(shù)全部放在請(qǐng)求體中
  • 理論上啰挪,POST傳遞的數(shù)據(jù)量沒(méi)有限制(具體還得看服務(wù)器的處理能力)
  • 如果要傳遞大量數(shù)據(jù)信不,比如文件上傳,只能用POST請(qǐng)求
  • GET的安全性比POST要差些脐供,如果包含機(jī)密\敏感信息浑塞,建議用POST
  • 如果是增加、修改政己、刪除數(shù)據(jù)酌壕,建議使用POST
5、iOS中發(fā)送HTTP請(qǐng)求的方案
5.1歇由、蘋果原生(自帶)
  • NSURLConnection:用法簡(jiǎn)單卵牍,最古老最經(jīng)典最直接的一種方案【坑比較多】
  • NSURLSession:功能比NSURLConnection更加強(qiáng)大,蘋果目前比較推薦使用這種技術(shù)【2013推出沦泌,iOS7開(kāi)始出的技術(shù)】
  • CFNetwork:NSURL*的底層糊昙,純C語(yǔ)言
5.2、第三方框架
  • ASIHttpRequest:外號(hào)“HTTP終結(jié)者”谢谦,功能極其強(qiáng)大释牺,可惜早已停止更新
  • AFNetworking:簡(jiǎn)單易用,提供了基本夠用的常用功能回挽,維護(hù)和使用者多
  • MKNetworkKit:簡(jiǎn)單易用没咙,維護(hù)和使用者少
6、HTTP通信過(guò)程
6.1千劈、請(qǐng)求
  • HTTP協(xié)議規(guī)定:1個(gè)完整的由客戶端發(fā)給服務(wù)器的HTTP請(qǐng)求中包含以下內(nèi)容
  • 請(qǐng)求頭:包含了對(duì)客戶端的環(huán)境描述祭刚、客戶端請(qǐng)求信息等
  • GET /minion.png HTTP/1.1 // 包含了請(qǐng)求方法、請(qǐng)求資源路徑、HTTP協(xié)議版本
  • Host: 120.25.226.186:32812 // 客戶端想訪問(wèn)的服務(wù)器主機(jī)地址
  • User-Agent: Mozilla/5.0 // 客戶端的類型涡驮,客戶端的軟件環(huán)境
  • Accept: text/html, / // 客戶端所能接收的數(shù)據(jù)類型
  • Accept-Language: zh-cn // 客戶端的語(yǔ)言環(huán)境
  • Accept-Encoding: gzip // 客戶端支持的數(shù)據(jù)壓縮格式
  • 請(qǐng)求體:客戶端發(fā)給服務(wù)器的具體數(shù)據(jù)暗甥,比如文件數(shù)據(jù)(POST請(qǐng)求才會(huì)有)
6.2、響應(yīng)
  • 客戶端向服務(wù)器發(fā)送請(qǐng)求捉捅,服務(wù)器應(yīng)當(dāng)做出響應(yīng)撤防,即返回?cái)?shù)據(jù)給客戶端
  • HTTP協(xié)議規(guī)定:1個(gè)完整的HTTP響應(yīng)中包含以下內(nèi)容:
  • 響應(yīng)頭:包含了對(duì)服務(wù)器的描述、對(duì)返回?cái)?shù)據(jù)的描述:
  • HTTP/1.1 200 OK // 包含了HTTP協(xié)議版本锯梁、狀態(tài)碼即碗、狀態(tài)英文名稱
  • Server: Apache-Coyote/1.1 // 服務(wù)器的類型
  • Content-Type: image/jpeg // 返回?cái)?shù)據(jù)的類型
  • Content-Length: 56811 // 返回?cái)?shù)據(jù)的長(zhǎng)度
  • Date: Mon, 23 Jun 2014 12:54:52 GMT // 響應(yīng)的時(shí)間
  • 響應(yīng)體:服務(wù)器返回給客戶端的具體數(shù)據(jù),比如文件數(shù)據(jù)
6.3陌凳、常見(jiàn)的響應(yīng)狀態(tài)碼
常見(jiàn)服務(wù)器響應(yīng)的狀態(tài)碼

三、NSURLConnection

1内舟、NSURLConnection的使用步驟
  • 創(chuàng)建一個(gè)NSURL對(duì)象合敦,設(shè)置請(qǐng)求路徑
  • 傳入NSURL創(chuàng)建一個(gè)NSURLRequest對(duì)象,設(shè)置請(qǐng)求頭和請(qǐng)求體(POST請(qǐng)求的時(shí)候使用NSMutableURLRequest設(shè)置請(qǐng)求體验游,GET和POST請(qǐng)求頭已經(jīng)默認(rèn)設(shè)置好了)
  • 使用NSURLConnection發(fā)送請(qǐng)求
1.1充岛、NSURLConnection使用圖示
NSURLConnection使用圖示
2.NSURLConnection實(shí)際使用
2.1、NSURLConnection的基本使用
//發(fā)送異步請(qǐng)求:不會(huì)卡住當(dāng)前線程
- (void)async{
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"%@", string);
        //獲取響應(yīng)頭信息
        NSHTTPURLResponse *r = (NSHTTPURLResponse *)response;
        NSLog(@"%zd %@", r.statusCode, r.allHeaderFields);
    }];
}

//發(fā)送同步請(qǐng)求:卡住當(dāng)前線程耕蝉,直到請(qǐng)求完成
- (void)sync{
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=123&pwd=345"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSHTTPURLResponse *response = nil;
    NSError *error = nil;
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    
    NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"%@ %@", string, response.allHeaderFields);
}
2.2崔梗、NSURLConnection的代理方式:拿到connection對(duì)象調(diào)用cancel方法可以取消請(qǐng)求
- (void)delegateAysnc{
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    [NSURLConnection connectionWithRequest:request delegate:self];//自動(dòng)請(qǐng)求
    //[[NSURLConnection alloc] initWithRequest:request delegate:self];//自動(dòng)請(qǐng)求

    //startImmediately:YES:立即自動(dòng)請(qǐng)求,NO:調(diào)用conn的start方法才會(huì)請(qǐng)求
    //NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
}

//<NSURLConnectionDataDelegate>
// 接收到服務(wù)器的響應(yīng)
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
}
 //接收到服務(wù)器的數(shù)據(jù)(如果數(shù)據(jù)量比較大,這個(gè)方法會(huì)被調(diào)用多次)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
}
//服務(wù)器的數(shù)據(jù)成功接收完畢
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
}
//請(qǐng)求失斃菰凇(比如請(qǐng)求超時(shí))
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
}
2.3蒜魄、NSMutableURLRequest簡(jiǎn)介
//設(shè)置請(qǐng)求超時(shí)等待時(shí)間(超過(guò)這個(gè)時(shí)間就算超時(shí),請(qǐng)求失敵∏)
- (void)setTimeoutInterval:(NSTimeInterval)seconds;

//設(shè)置請(qǐng)求方法(比如GET和POST)
- (void)setHTTPMethod:(NSString *)method;

//設(shè)置請(qǐng)求體
- (void)setHTTPBody:(NSData *)data;

//設(shè)置請(qǐng)求頭
- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field;

2.4谈为、NSURLConnection發(fā)送POST請(qǐng)求
- (void)sendPOSTRequest {
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    request.HTTPMethod = @"POST";
    request.HTTPBody = [@"username=520it&pwd=520it" dataUsingEncoding:NSUTF8StringEncoding];
    request.timeoutInterval = 5;
    // 設(shè)置請(qǐng)求頭
    //[request setValue:@"iOS 9.0" forHTTPHeaderField:@"User-Agent"];
    
    // 3.發(fā)送請(qǐng)求
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
    }];
}
2.5、URL中文轉(zhuǎn)碼
//URL中包含中文的話需要進(jìn)行轉(zhuǎn)碼踢关,否則識(shí)別不了
- (nullable NSString *)stringByAddingPercentEscapesUsingEncoding:(NSStringEncoding)enc;

四伞鲫、JSON&XML

1、JSON
  • 第三方框架:JSONKit签舞、SBJson秕脓、TouchJSON(性能從左到右,越差)
  • 蘋果原生(自帶):NSJSONSerialization(性能最好)
+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;
+ (NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error;
2儒搭、XML
  • 全稱是Extensible Markup Language吠架,譯作“可擴(kuò)展標(biāo)記語(yǔ)言”,跟JSON一樣,也是常用的一種用于交互的數(shù)據(jù)格式,一般也叫XML文檔(XML Document)
  • 一個(gè)常見(jiàn)的XML文檔一般由以下部分組成:
    文檔聲明
    元素(Element)
    屬性(Attribute)
2.1师妙、文檔聲明
  • 在XML文檔的最前面诵肛,必須編寫一個(gè)文檔聲明,用來(lái)聲明XML文檔的類型
  • 最簡(jiǎn)單的聲明:
    <?xml version="1.0" ?>
  • 用encoding屬性說(shuō)明文檔的字符編碼:
    <?xml version="1.0" encoding="UTF-8" ?>
2.2、元素(Element)
  • 一個(gè)元素包括了開(kāi)始標(biāo)簽和結(jié)束標(biāo)簽
  • 擁有內(nèi)容的元素:<video>小黃人</video>
  • 沒(méi)有內(nèi)容的元素:<video></video>
  • 沒(méi)有內(nèi)容的元素簡(jiǎn)寫:<video/>
  • 一個(gè)元素可以嵌套若干個(gè)子元素(不能出現(xiàn)交叉嵌套)


    元素嵌套
  • 規(guī)范的XML文檔最多只有1個(gè)根元素怔檩,其他元素都是根元素的子孫元素
2.3褪秀、屬性(Attribute)
  • 一個(gè)元素可以擁有多個(gè)屬性
    <video name="小黃人 第01部" length="30" />
  • video元素?fù)碛衝ame和length兩個(gè)屬性
  • 屬性值必須用 雙引號(hào)"" 或者 單引號(hào)'' 括住
3、XML的解析
3.1薛训、DOM&SAX
  • DOM:一次性將整個(gè)XML文檔加載進(jìn)內(nèi)存媒吗,比較適合解析小文件
  • SAX:從根元素開(kāi)始,按順序一個(gè)元素一個(gè)元素往下解析乙埃,比較適合解析大文件
3.2闸英、解析方式
  • 蘋果原生
    NSXMLParser:SAX方式解析,使用簡(jiǎn)單
  • 第三方框架
    libxml2:純C語(yǔ)言介袜,默認(rèn)包含在iOS SDK中甫何,同時(shí)支持DOM和SAX方式解析
    GDataXML:DOM方式解析,由Google開(kāi)發(fā)遇伞,基于libxml2
  • XML解析方式的選擇建議
    大文件:NSXMLParser辙喂、libxml2
    小文件:GDataXML、NSXMLParser鸠珠、libxml2
3.3巍耗、GDataXML的配置

3.3.1、GDataXML下載地址 密碼:hsfn
3.3.2渐排、導(dǎo)入libxml2庫(kù):

導(dǎo)入libxml2庫(kù)

3.3.3炬太、設(shè)置libxml2的頭文件搜索路徑(為了能找到libxml2庫(kù)的所有頭文件):在Head Search Path中加入/usr/include/libxml2
3.3.4、設(shè)置鏈接參數(shù)(自動(dòng)鏈接libxml2庫(kù):在Other Linker Flags中加入-lxml2

3.4驯耻、NSXMLParser解析示例:
//XML大致格式
<videos>
    <video id="1" name="xxx" length="xxx" url="xxx" image= "xxx"/>
    <video id="2" name="xxx" length="xxx" url="xxx" image= "xxx"/>
    <video id="3" name="xxx" length="xxx" url="xxx" image= "xxx"/>
</videos>
- (void)NSXMLParserTest {
    [super viewDidLoad];
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/video?type=XML"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
        parser.delegate = self;
        [parser parse];//會(huì)阻塞當(dāng)前線程
    }];
}

#pragma mark - <NSXMLParserDelegate>

//解析到某個(gè)元素的結(jié)尾(比如解析</videos>)
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
}

// 解析到某個(gè)元素的開(kāi)頭(比如解析<videos>)
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
    if ([elementName isEqualToString:@"videos"]) return;
    VideoModel *video = [VideoModel objectWithKeyValues:attributeDict];
    [self.videos addObject:video];
}


//開(kāi)始解析XML文檔
- (void)parserDidStartDocument:(NSXMLParser *)parser{
}

//解析完畢
- (void)parserDidEndDocument:(NSXMLParser *)parser{
}
3.5亲族、GDataXML解析示例:
//XML大致格式
<videos>
    <video id="1" name="xxx" length="xxx" url="xxx" image= "xxx"/>
    <video id="2" name="xxx" length="xxx" url="xxx" image= "xxx"/>
    <video id="3" name="xxx" length="xxx" url="xxx" image= "xxx"/>
</videos>
- (void)GDataXMLTest {
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/video?type=XML"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        // 加載整個(gè)文檔
        GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data options:0 error:nil];
        
        // 獲得所有video元素
        NSArray *elements = [doc.rootElement elementsForName:@"video"];
        for (GDataXMLElement *ele in elements) {
            VideoModel *video = [[VideoModel alloc] init];
            video.name = [ele attributeForName:@"name"].stringValue;
            video.url = [ele attributeForName:@"url"].stringValue;
            video.image = [ele attributeForName:@"image"].stringValue;
            video.length = [ele attributeForName:@"length"].stringValue.integerValue;
            
            [self.videos addObject:video];
        }
    }];
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市吓歇,隨后出現(xiàn)的幾起案子孽水,更是在濱河造成了極大的恐慌,老刑警劉巖城看,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件女气,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡测柠,警方通過(guò)查閱死者的電腦和手機(jī)炼鞠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)轰胁,“玉大人谒主,你說(shuō)我怎么就攤上這事≡叻В” “怎么了霎肯?”我有些...
    開(kāi)封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我观游,道長(zhǎng)搂捧,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任懂缕,我火速辦了婚禮允跑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘搪柑。我一直安慰自己聋丝,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布工碾。 她就那樣靜靜地躺著弱睦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪渊额。 梳的紋絲不亂的頭發(fā)上每篷,一...
    開(kāi)封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音端圈,去河邊找鬼。 笑死子库,一個(gè)胖子當(dāng)著我的面吹牛舱权,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播仑嗅,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼宴倍,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了仓技?” 一聲冷哼從身側(cè)響起鸵贬,我...
    開(kāi)封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎脖捻,沒(méi)想到半個(gè)月后阔逼,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡地沮,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年嗜浮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摩疑。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡危融,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出雷袋,到底是詐尸還是另有隱情吉殃,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站蛋勺,受9級(jí)特大地震影響瓦灶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜迫卢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一倚搬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧乾蛤,春花似錦每界、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至上荡,卻和暖如春趴樱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背酪捡。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工叁征, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人逛薇。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓捺疼,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親永罚。 傳聞我的和親對(duì)象是個(gè)殘疾皇子啤呼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354